我正在尝试添加两个4位(16位(BCD数字并显示结果。
我已经写了下面的代码,但我想知道我如何处理进位位,因为这个程序挂断了DosBox(TASM Emulator(
出于某种原因,我的教授希望我们显示输入输出,请耐心等待:/
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,4
mov bx,0
l3:
shl dx,4
mov ah,01
int 21h
and al,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
(。您需要一个循环,从存储在CH
寄存器的高位半字节中的最高有效位数字开始,在4个BCD数字上迭代。
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
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
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