用汇编语言实现两个数相加,并考虑进位情况(两个数都是用一个字节储存的)
1. 首先贴代码
assume cs:code,ds:data
data segment
op1 DB 09h
op2 DB 08h
defult db ?
carry db ?
data ends
code segment
start:
mov ax,data
mov ds,ax
mov al,op1
add al,op2
AAA
jc ss2
jnc ss1
ss1:mov carry,30H
ss2:mov carry,31h
ss3:mov defult,al
add defult,30h
mov dl,carry
mov ah,2
int 21h
mov dl,defult
mov ah,2
int 21h
mov ah,4ch
int 21h
code ends
end start
2 .方法
首先将操作数(operand)op1与op2的和存到寄存器al中,
然后利用AAA命令将al中的值调整到非压缩的BCD格式.
之后用jc和jnc命令判断是否有进位,
如果有,将carry赋值为31h,否则将carry赋值为30h,
并将al中的值赋给defult,之后把defult转换成字符的形式,
最后分别打印出carry(表示结果的高八位)和defult(结果的低八位)即可.
3. 解释
(1) AAA指令:将al中的值调整到非压缩的BCD格式
比如执行 ADD AL,BL 之后,AL的值是15,AAA调整后变成用AH、AL表示非压缩BCD码的15,即AH=1,AL=5,不影响其它通用寄存器的值。
(2) jc、jnc和jmp指令
jc:当cf=1(即进位标志位为1,也就是说进位了)时,则转移.
上文代码中命令 jc ss2 ,意思就是转移到了ss2.之后执行ss2和其之后的语句,而不会返回到跳转语句并执行其后的语句.
jnc:当cf=0(即进位标志位为0,也就是没有进位)时,则转移.
上文代码中命令 jnc ss1 ,意思就是转移到了ss1.之后执行ss2和其之后的语句,而不会返回到跳转语句并执行其后的语句.
这两个代码用于对 是否进位 的判断.
jmp:表示无条件的转移.如同上文两个跳转命令一样,也不会返回.
(3) 为什么把31h/30h赋给carry
查找ASCII['æski]表,可以知道30h/31h表示序号48/49,分别对应着ASCII表中的十进制数0/1,也就是说如果进位,则把carry赋值为1,如果不进位,把carry赋值为0.其中carry表示为结果的高八位.
(4) 如何将defult中的值转变成字符类型的十进制数?
执行指令 add defult,30h.
因为30h是ASCII表中十进制数 0 的序号,所以defult中的值加上30h之后就可以转变成字符类型的十进制数.
参考资料:
加法的非压缩BCD码调整指令AAA:
https://bbs.csdn.net/topics/290073229
汇编 简单的两个一位数相加
https://blog.csdn.net/iaiti/article/details/9348421