I have this problem with the code below which converts number to ASCII ‘number-text’. However the code seems to loop at the ‘div’ opcode
;Main Program
main:
mov ax, 0x0000
mov ds, ax ; setup data segment register
mov si, GreetString ; setup data segment offset
call print_string ; call print string procedure
mov si, DataWord ; setup data segment offset
mov bl, 0x000A ; base 10
call format_string ; call format string procedure
mov si, GreetString ; setup data segment offset
call print_string ; call print string procedure
prevent_overflow:
hlt ; halt the CPU
jmp prevent_overflow
format_string:
mov ax, [ds:si] ; load register ax with data
xor cx, cx ; set counter to 0
mov si, GreetString ; set pointer to address of GreetString
.format_char:
div bl ; divides by register bl
add ah, 48 ; convert to ascii numeric
mov [ds:si], ah ; move ascii numeric to ds:si
inc cx ; increase counter
inc si ; increase si
xor ah, ah ; clear ah register
or ax, ax
jnz .format_char ; jump to format next char
ret
Any idea why does this happen? I say ‘loop’ because my CPU is at max-value and does not proceed with the opcodes after div
*Updated. Thanks newgre. Added main section to make it more readable (^.^)
The problem is that you get a division overflow exception because the quotient (in my example below it’s 12345 div 10 = 1234 + remainder of 5) doesn’t fit into the 8 bits of
al(remember thatahis already used by the remainder?).Every time either the quotient or the remainder doesn’t fit into the destination register you get a division overflow exception. It’s not only the division by 0 that causes it.
You want to do a 32/16=16:16 division instead of a 16/8=8:8 division.
Here’s what works in DOS with my changes (marked as
;;;):It prints: