简体   繁体   English

16 位(4 位)BCD 加法(TASM 8086)

[英]16 bit (4 digits) BCD addition (TASM 8086)

I am trying to add two 4 digits (16 bit) BCD numbers and display the result.我正在尝试添加两个 4 位(16 位)BCD 数字并显示结果。

I have written the code below but I want to know how do I handle the carry bit because this program is hanging up DosBox (TASM Emulator)我写了下面的代码,但我想知道如何处理进位位,因为这个程序正在挂起 DosBox (TASM Emulator)

For some reason my professor wanted us to display the input-output, please bear with me:/出于某种原因,我的教授希望我们显示输入输出,请耐心等待:/

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

Also, am I doing something wrong in the code?另外,我在代码中做错了什么吗?

For the input of the second number you are resetting the BX register and thus are destroying the first inputted number .对于第二个数字的输入,您正在重置BX寄存器,从而破坏了第一个输入的数字 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.现在的美妙之处在于您根本不需要将目标寄存器置零,因为将一个字寄存器移位 4 位并执行 4 次将不会留下任何预先写入的内容。 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.您的级联 BCD 加法使用AH寄存器,但该寄存器在程序的那个点没有任何用处 You should have used the DH register instead.您应该改用DH寄存器。

At the end of the addition the CX register holds a 4-digit packed BCD.在加法结束时, CX寄存器保存一个 4 位压缩 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 ).不能使用 DOS.PrintCharacter function 02h 在一个 go 中打印它,其中function 号码转到AH (而不是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.您需要一个循环遍历 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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM