汇编入门(二)

汇编入门(二)

RLC,RRC  A      带进位累加器循环左移/右移
JC,JNC  rel     进位为1/0时转移
JB,JNB bit,rel  某一位为1/0时转移
INC,DEC A       寄存器加1/减1
DJNZ Rn rel     寄存器减一,不为0则转移(循环转移指令)

1.输出0-1转变的次数到累加器A中
RLC:
在这里插入图片描述
JNB:
在这里插入图片描述

;0-1转变的次数 累加器A中
ORG 0000H

MOV 	A,#10101011B
MOV 	R1,#0
MOV		R2,#7

L0: RLC A          ;带进位累加器循环左移,A最高位的值放在C里
	JC L1          ;如果进位位为1 则转移到L1; JC进位为1转移,JNC进位为0转移
	JNB ACC.7,L1   ;判断ACC的第7位是否为0 若是则转移到L1; 
	INC R1         ;R1加1
L1: DJNZ R2,L0     ;R2减1,若不为0 则转移到L0


MOV A,R1
END

2.已知s=’…’ 的字符串,以0结束。问a=’ ',是否在s中

ORG 0000H        ;伪指令,定义下面的指令所在地址,此句为主程序开始地址
LJMP MAIN        ;无条件转移到MAIN
MAIN:
	MOV DPTR,#S
	MOV B,#m
	L1:
	    CLR A
	    MOVC A,@A+DPTR    ;将A中的值,加上DPTR里的值,访问程序段中这个地址的值,取出来送给A。
	    INC DPTR          ;自加1,准备读取下一个字符
	    JZ LEND           ;这是条件跳转语句,意思是,当累加器A中的值为0时,即到达字符串末尾,跳转到LEND语句行执行程序

		CJNE A,B,L1       ;判断A和B是否相等,相等则顺序执行,不相等则执行L1
		MOV A,#'Y'
		SJMP LEND2

	LEND:
		MOV A,#'N'
		SJMP LEND2
	LEND2:
		RET
		
	s: DB'HELLO'          ;DB定义数据表
	m EQU 'L'             ;EQU给一个表达式或一个字符串起名
	  
END              ;程序结束

在这里插入图片描述

ORG 0000H        ;伪指令,定义下面的指令所在地址,此句为主程序的开始地址
LJMP MAIN        ;无条件转移到MAIN
MAIN:            ;主程序
//赋值
	HEX0 DATA 83H ;存16进制高八位,这里对应DPTR,便于调试
	HEX1 DATA 82H ;存16进制低八位
	DEC0 DATA 05H ;存BCD高高八位
	DEC1 DATA 06H ;存BCD高八位
	DEC2 DATA 07H ;存BCD低八位
	MOV HEX0,#0
	MOV HEX1,#0
	MOV DEC0,#07H
	MOV DEC1,#55H
	MOV DEC2,#35H

//十进制数不能大于65535,MUL大于65535会溢出,故大于65535直接无效,OV=1
	//高高位大于7直接无效
	MOV A,#0F0H  ;高位不为0直接跳转
	ANL A,DEC0
	CJNE A,#0,FLOWOUT
	//低位大于7也直接跳转
	MOV A,#0FH    
	ANL A,DEC0
	ADD A,#9    ;7+9=16会进一位
	MOV R4,#0F0H  
	MOV 71H,R4
	ANL A,R4
	MOV 70H,A
	CJNE A,#0,FLOWOUT
	
	

//将DEC0,1,2中分别转换为十六进制,5个数放入以60H开始的地址中
	MOV R0,#05H
	MOV R1,#60H
	MOV R3,#3
L0:
	MOV A,@R0
	ANL A,#0F0H
	SWAP A
	MOV @R1,A
	INC R1
	MOV A,@R0
	ANL A,#0FH
	MOV @R1,A
	INC R1
	INC R0
	DJNZ R3,L0
	
	
	//开始对5个数循环处理
	MOV R1,#60H ;下一个储存单元从61H开始
	MOV R2,#5;循环5次
L1:
	//由于数在寄存器中显示出的就是其十六进制的值,所以把数一位一位放进去就好了
	//注意低位和高位
	MOV HEX1,54H  ;暂存数放到低位
	MOV HEX0,53H  ;暂存数放到高位
	
	INC R1
	MOV A,@R1  ;取一位放到A
	ADD A,HEX1  ;相加后放到低位
	MOV HEX1,A
	MOV A,#0   ;计算高位
	ADDC A,HEX0 ;
	MOV HEX0,A  ;相加后放到高位
	
	//计算阶段
	MOV 54H,#0
	MOV 53H,#0
	MOV A,HEX1  ;取低位×10
	MOV B,#10
    MUL AB
	MOV 54H,A  ;暂存低八位
	MOV 53H,B  ;暂存高八位

	MOV A,HEX0  ;取高位×10
	MOV B,#10
	MUL AB     ;MUL的结果高8位放在B,低8位放在A
    ADD A,53H  ;将计算得到的低八位和上次计算得到的高八位相加
	MOV 53H,A	   	
	DJNZ R2,L1

FLOWOUT: SETB OV
	
STOP:	SJMP $    
END              ;程序结束

在这里插入图片描述
1)方法一:借用二进制移位
在这里插入图片描述

//在寄存器中8位二进制数与2位十六进制数是一个东西
//所以我们要做的只是把十六进制数看作二进制的数一位一位用RLC取出
//分别放到三个寄存器中即可

MOV R0,#0C8H
MOV R1,#0A1H
CLR A
MOV R2, A ;存转换后的十进制数高位
 MOV R3, A 	; 存转换后的十进制数千百位
 MOV R4, A 	; 存转换后的十进制数十个位
 MOV R5, #16 ;共转换十六位二进制数
 
LOOP:
//注意RLC是左移一位,尾部的值是由当前cy的值进上去的,头部的值再移到cy中更新cy
//低位与高位为一个整体,所以低位左移去出的cy补到高位尾部,形成一个整体
 CLR C
 MOV A, R1 ;从低位开始
 RLC A
 MOV R1, A
 
 MOV A, R0 ;高位尾部的进位取决于低位左移出的cy 
 RLC A
 MOV R0, A
 
//之后一位一位往上加即可
 MOV A, R4 ;送到BCD码的位
 ADDC A, R4 ;自身相加,即为×2操作
 DA A ;十进制调整,变成BCD码
 MOV R4, A
 
 MOV A, R3
 ADDC A, R3	;使上一次十进制调整的结果导致进位加到这一位上
 DA A
 MOV R3, A
 
 MOV A, R2
 ADDC A, R2 ;使上一次十进制调整的结果导致进位加到这一位上
 MOV R2, A	;不必再十进制调整,两种进制小于10时相等
 DJNZ R5, LOOP ;共转换十六位二进制数

2)方法二:位权法十六进制转十进制:
设十六进制数:H3,H2,H1,H0四位
十进制=16^3 * H3+16 ^2 * H2+16 *H1+H0
提取16得:16 *(16 *(16 * H3+H2)+H1)+H0
此时可以使用循环来编写程序了,但因为乘16不能直接用MUL,所以需要对自身H0自加4次达到16 *H0效果

ORG 0000H        ;伪指令,定义下面的指令所在地址,此句为主程序开始地址
LJMP MAIN        ;无条件转移到MAIN
MAIN:

	HEX0 EQU 30H ;存16进制高八位,这里对应DPTR,便于调试
	HEX1 EQU 31H ;存16进制低八位
	DEC0 EQU 40H
	DEC1 EQU 41H
	DEC2 EQU 42H

	MOV HEX0,#12H
	MOV HEX1,#34H
	
	MOV R0,#30H    //注意这里R0存的是数30H,这样INC R0就是指向下一个,@R0才是他的元素的值
	MOV R1,#60H
	MOV R2,#3
	MOV R3,#3
	MOV R4,#4
	
	L0:             //一位一位拿出来,放到以60H开始的地址中
		MOV A,@R0
		ANL A,#0F0H
		SWAP A
		MOV @R1,A
		INC R1
		MOV A,@R0
		ANL A,#0FH
		MOV @R1,A
		INC R1
		INC R0
		DJNZ R2,L0
		
		MOV R1,#60H  //重新指向开头
		
		MOV DEC2,@R1  //先拿出第一个数
		INC R1
	L1:
		MOV 50H,@R1
		INC R1
		MOV R4,#4       //别忘了
		
	L2:               //乘16
		CLR C
		MOV A,DEC2
		ADDC A,DEC2
		DA A
		MOV DEC2,A
		
		MOV A,DEC1
		ADDC A,DEC1
		DA A
		MOV DEC1,A
		
		MOV A,DEC0
		ADDC A,DEC0
		DA A
		MOV DEC0,A
		DJNZ R4,L2
		
	L3:             //加
		CLR C
		MOV A,50H
		ADDC A,DEC2
		DA A
		MOV DEC2,A
		
		MOV A,DEC1
		ADDC A,DEC1
		DA A
		//MOV DEC1,A
		
		MOV A,DEC0
		ADDC A,DEC0
		DA A
		MOV DEC0,A
		
		DJNZ R3,L1
		
SJMP $       ;转到该指令的开头开始执行	  
END              ;程序结束

猜你喜欢

转载自blog.csdn.net/weixin_44026026/article/details/109475705