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,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