Mihai Daian
Mihai Daian

Reputation: 33

Printing an integer in assembly x86

I want to print an integer with this code but when i assemble with tasm and run program.exe in dosbox, nothing happens and i think it goes into an infinite loop. Do you have an idea?

data segment para public 'data'
data ends

mycode segment para public 'code'
assume cs:mycode, ds:data

main proc far

    push ds
    xor ax, ax
    push ax
    mov ax, data
    mov ds, ax
    
    mov ax, 123
    mov cx, 0
    
    loop_count:
        mov bl, 10
        inc cx
        div bl
        mov dl, al
        mov al, ah
        xor ah, ah
        push ax
        xor ah, ah
        mov ax, dx
        cmp ax, 0
        jne loop_count
    
    
    loop_print:
        pop dx
        add dx, 30h
        mov ah, 02h
        int 21h
        loop loop_print
        
ret

main endp
mycode ends
end main

Upvotes: 0

Views: 443

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

You can find a detailed explanation about printing an integer in Displaying numbers with DOS.

mov dl, al    ; Preserve quotient
mov al, ah    ; \
xor ah, ah    ;  Store a 'cleaned' remainder
push ax       ; /
xor ah, ah
mov ax, dx    ; Restore quotient

You want to store the current remainder on the stack, and you want to store it in a 'cleaned' fashion (with its high byte zero). Because both quotient and remainder are in the AX register, you had to first preserve the current quotient in another register like DL, but for the restoration you used the whole DX register with no guarantee that DH would be empty! This produced a runaway loop.

You can solve this in a number of ways, but I think you should not try to 'clean' what you push on the stack. Use the second loop where you need the character in DL anyway.

This is how printing the byte in AL looks like:

  mov  al, 123

  mov  bl, 10
  mov  cx, sp
loop_count:
  xor  ah, ah
  div  bl
  push ax           ; Remainder is in AH, don't care about AL
  test al, al
  jnz  loop_count
    
loop_print:
  pop  ax           ; Remainder is in AH, don't care about AL
  mov  dl, ah
  add  dl, '0'
  mov  ah, 02h
  int  21h
  cmp  sp, cx
  jb   loop_print

Upvotes: 2

Related Questions