用汇编语言实现两个数相加,并考虑进位情况(两个数都是用一个字节储存的)

用汇编语言实现两个数相加,并考虑进位情况(两个数都是用一个字节储存的)

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

你可能感兴趣的:(用汇编语言实现两个数相加,并考虑进位情况(两个数都是用一个字节储存的))