Reputation: 33
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
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