2

when i sum two numbers like
(1111 1111 1111 1111)h + (1111 1111 1111 1111)h
it display the result is (2000 20000 2000 2000)h
where the true result is (2222 2222 2222 2222)h

;the code
.model small
.stack 100h

.data
    num1 dw 1111h, 1111h, 1111h, 1111h ; ÇáÚÏÏ ÇáÃæá
    num2 dw 1111h, 1111h, 1111h, 1111h ; ÇáÚÏÏ ÇáËÇäí
    result dw 0, 0, 0, 0               ; äÊíÌÉ ÇáÌãÚ
    msg db 'Result: $'                 ; ÑÓÇáÉ ÇáØÈÇÚÉ

.code
main:
    mov ax, @data
    mov ds, ax
    mov es, ax

    ; ÊÍãíá ÇáÌÒÁ ÇáÃæá ãä ÇáÚÏÏ ÇáÃæá Ýí ÇáÓÌáÇÊ
    mov ax, word ptr num1
    mov bx, word ptr num1+2
    mov cx, word ptr num1+4
    mov dx, word ptr num1+6

    ; ÅÖÇÝÉ ÇáÌÒÁ ÇáÃæá ãä ÇáÚÏÏ ÇáËÇäí
    add ax, word ptr num2
    adc bx, word ptr num2+2
    adc cx, word ptr num2+4
    adc dx, word ptr num2+6

    ; ÊÎÒíä ÇáäÊíÌÉ
    mov word ptr result, ax
    mov word ptr result+2, bx
    mov word ptr result+4, cx
    mov word ptr result+6, dx

    ; ØÈÇÚÉ ÇáÑÓÇáÉ
    lea dx, msg
    mov ah, 09h
    int 21h

    ; ØÈÇÚÉ ÇáäÊíÌÉ
    mov ax, word ptr result+6
    call print_hex
    mov ax, word ptr result+4
    call print_hex
    mov ax, word ptr result+2
    call print_hex
    mov ax, word ptr result
    call print_hex

    ; ÅäåÇÁ ÇáÈÑäÇãÌ
    mov ah, 4Ch
    int 21h

print_hex:
    ; ØÈÇÚÉ ÇáÞíãÉ Ýí AX ßÑÞã ÓÏÇÓí ÚÔÑí
    push ax
    push bx
    push cx
    push dx

    mov bx, 4
    mov cx, 4

print_loop:
    rol ax, 4
    mov dl, al
    and dl, 0Fh
    add dl, '0'
    cmp dl, '9'
    jle print_char
    add dl, 7

print_char:
    mov ah, 02h
    int 21h
    loop print_loop

    pop dx
    pop cx
    pop bx
    pop ax
    ret

end main
1
  • 5
    Your printing is broken. ah is part of ax so you destroy the value. Should have tested the printing without the addition first and/or use a debugger. Commented Sep 21, 2024 at 21:58

1 Answer 1

3

The quick fix.

As @Jester pointed out in a comment your instruction mov ah, 02h overwrites your AX that is input to the print_hex routine. But also the int 21h DOS function itself modifies AL with a copy of DL (that you provided). So you destroyed 3/4 of the input value!
You can solve this issue with no extra bytes. Simply move the existing push ax and pop ax to just around the DOS invokation. In the end the AX register still gets preserved because the 4 executions of rol ax, 4 will return the value to what it was at the start:

print_hex:
    push cx
    push dx
    mov  cx, 4
print_loop:
    rol  ax, 4
    mov  dl, al
    and  dl, 0Fh
    add  dl, '0'
    cmp  dl, '9'
    jbe  print_char
    add  dl, 7
print_char:
    push ax                  ; New place
    mov  ah, 02h
    int  21h
    pop  ax                  ; New place
    loop print_loop
    pop  dx
    pop  cx
    ret
  • The code wasn't using BX, so I removed those lines
  • ASCII codes are to be treated as unsigned numbers, therefore I replaced jle by jbe

Why not print it all at once?

First set up a buffer that can hold your 16 hex characters. If you place it adjacent to the message, you'll only need one invokation of the DOS PrintString function:

msg db 'Result: '
buf db 16 dup(0), '$'

Then the printing part of your program becomes:

    ...

    mov  di, offset buf
    mov  si, 6
NextWord:
    mov  dx, [result + si]
    call stos_hex            ; -> DI (AL CX)
    sub  si, 2
    jnb  NextWord            ; Repeat for SI = {4,2,0}

    lea  dx, msg
    mov  ah, 09h             ; DOS.PrintString
    int  21h

    mov  ax, 4C00h           ; DOS.Terminate
    int  21h
; -------------------------------
; IN (dx,di) OUT (di) MOD (al,cx)
stos_hex:
    mov  cx, 0404h           ; CH 4 hex digits, CL 4 bit rotations
stos_loop:
    rol  dx, cl
    mov  al, dl
    and  al, 0Fh
    add  al, '0'
    cmp  al, '9'
    jbe  stos_char
    add  al, 7
stos_char:
    stosb
    dec  ch
    jnz  stos_loop
    ret
  • Although accepts it (by actually inserting a wasteful series of single-shift instructions), true 8086 could not shift nor rotate via an immediate count, therefore I corrected the code using rol dx, cl with CL=4
  • It is fine to allow some of the registers to get clobbered. I did not care about the modifications to AL and CX
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.