问题描述
我正在尝试将两个4位(16位)BCD数字相加并显示结果。
我已经在下面编写了代码,但是我想知道我该如何处理进位,因为该程序挂断了DosBox(TASM仿真器)
model small
.data
res dw ?
.code
.startup
; 1st number
mov cx,4
mov bx,0
l1:
shl bx,4
mov ah,01
int 21h
and al,0FH
add bl,al
loop l1
mov ah,02h ; display + sign
mov dx,"+"
int 21h
; 2nd number
mov cx,0
l3:
shl dx,0FH
add dl,al
loop l3
mov al,bl
add al,dl
daa
mov cl,al # storing lower byte in clower
mov al,ah
adc al,bh
daa
mov ch,al # storing higher byte in c higher
mov [res],cx
mov ax,02h
mov dx,res # To display the result
int 21h
.EXIT
END
还有,我在代码中做错了吗?
解决方法
要输入第二个数字,您要重置BX
寄存器,从而销毁第一个输入的数字!现在的好处是,您根本不需要将目标寄存器归零,因为将一个字寄存器移位4位并执行4次将不会保留任何事先写入的内容。因此,只需删除这些初始值设定项即可。
您的级联BCD加法使用了AH
寄存器,但是该寄存器在程序中没有任何用处。您应该使用DH
寄存器。
加法结束时,CX
寄存器包含一个4位压缩的BCD。您无法使用DOS.PrintCharacter函数02h一次性打印该消息,该函数的功能编号转到AH
(而不是AX
)。您需要一个循环,该循环从最高有效数字开始的4个BCD数字进行迭代,该数字存储在CH
寄存器的高半字节中。
mov bx,4
More:
rol cx,4 ; Brings highest nibble round to lowest nibble
mov dl,cl ; Move to register that DOS expects
and dl,15 ; Isolate it
or dl,'0' ; Convert from value [0,9] to character ['0','9']
mov ah,02h ; DOS.PrintCharacter
int 21h
dec bx
jnz More
将它们放在一起并写一些更好的评论
call GetBCD ; -> DX
mov bx,dx
mov dl,'+' ; No need to store this in DX (DH is not used by DOS)
mov ah,02h ; DOS.PrintCharacter
int 21h
call GetBCD ; -> DX
mov al,bl
add al,dl
daa ; (*) -> CF
mov cl,al
mov al,bh
adc al,dh ; (*) Picking up the carry from above
daa
mov ch,al
mov bx,4 ; Brings highest nibble round to lowest nibble
mov dl,cl ; Move to register that DOS expects
and dl,15 ; Isolate it
or dl,'0' ; Convert from value [0,02h ; DOS.PrintCharacter
int 21h
dec bx
jnz More
mov ax,4C00h ; DOS.TerminateProgram
int 21h
; IN () OUT (dx)
GetBCD:
push ax
push cx
mov cx,4
T1:
mov ah,01h ; DOS.InputCharacter
int 21h ; -> AL=['0','9']
sub al,'0' ; -> AL=[0,9]
shl dx,4
or dl,al
loop T1
pop cx
pop ax
ret