assembly - 16 位(4 位)BCD 加法 (TASM 8086)
问题描述
我正在尝试添加两个 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,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
另外,我在代码中做错了吗?
解决方案
For the input of the second number you are resetting the BX
register and thus are destroying the first inputted number! Now the beauty is that you don't need to zero the destination register at all because shifting a word register by 4 bits and doing it 4 times will leave nothing that was written to it in advance. So just drop those initializers.
Your cascaded BCD addition uses the AH
register but that register has nothing useful in it at that point in the program. You should have used the DH
register instead.
At the end of the addition the CX
register holds a 4-digit packed BCD. You can not print that in one go using the DOS.PrintCharacter function 02h for which the function number goes to AH
(and not AX
). You need a loop that iterates over the 4 BCD digits starting at the most significand digit which is stored in the high nibble of the CH
register.
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
Putting it all together and writing some better comments
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
推荐阅读
- c# - 如何以编程方式重新停靠浮动窗口
- python - 用Python中的相同列表减去列表中的列表
- webpack - 在 VueJS 上集成引导主题的最佳方法是什么
- macos - 我如何让自己摆脱 Apple Developer ID 证书的混乱
- xamarin - Xamarin Forms Custom Renderer iOS UICollectionView 双向滚动/水平 - 垂直滚动
- javascript - 使用车把保持滚动位置
- javascript - 要从映射中获取不同字符串的数组,从映射值的属性中提取字符串
- binaryfiles - 计算包含某些字节的二进制文件的哈希
- sql - 你如何引用来自不同表单视图(ASP.NET)的数据
- ios - Near IF 语法错误(SQLite3+Objective-C)(如果不存在则更新)