简体   繁体   中英

16 bit (4 digits) BCD addition (TASM 8086)

I am trying to add two 4 digits (16 bit) BCD numbers and display the result.

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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