16-битное (4 цифры) двоично-десятичное сложение (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

Кроме того, я делаю что-то не так в коде?


person Dipesh Malhotra    schedule 11.10.2020    source источник
comment
Если вы говорите mov ax,02h перед отображением результата, это должно быть mov ah,02h, как и в предыдущем использовании. Удачи с этим, хотя, для отображения числа. MS-DOS не имеет функции вывода чисел.   -  person Weather Vane    schedule 11.10.2020


Ответы (1)


При вводе второго числа вы сбрасываете регистр BX и тем самым уничтожаете первое введенное число! Теперь красота в том, что вам вообще не нужно обнулять регистр назначения, потому что сдвиг регистра слов на 4 бита и выполнение этого 4 раза не оставит ничего из того, что было записано в него заранее. Так что просто отбросьте эти инициализаторы.

В вашем каскадном дополнении BCD используется регистр AH, но в этом регистре нет ничего полезного на данном этапе программы. Вместо этого вы должны были использовать регистр DH.

В конце сложения регистр CX содержит 4-значный упакованный двоично-десятичный код. Вы не можете распечатать это за один раз, используя функцию 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
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
person Sep Roland    schedule 18.10.2020