我在下面的代码中遇到此问题,该代码将数字转换为ASCII“数字文本”。然而,代码似乎循环在'div'操作码
;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
知道为什么会这样吗?我说'循环'是因为我的CPU处于最大值并且在div之后没有进行操作码
*更新。谢谢newgre。添加了主要部分以使其更具可读性(^。^)
答案 0 :(得分:2)
问题是你得到一个除法溢出异常,因为商(在我的例子下面是12345 div 10 = 1234 +剩余5)不适合al
的8位(记住{其余部分已经使用了{1}}。
每当商或余数不适合目标寄存器时,就会出现除法溢出异常。这不仅仅是0的除法导致它。
你想做一个32/16 = 16:16分区而不是16/8 = 8:8分区。
这是在DOS中使用我的更改(标记为ah
):
;;;
打印:
; file: div2.asm
; compile as: nasm -f bin div2.asm -o div2.com
org 0x100 ;;;
;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
ret ;;;
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 ;;;
xor dx, dx ;;;
xor bh, bh ;;;
div bx ;;;
; add ah, 48 ; convert to ascii numeric ;;;
add dl, 48 ;;;
; mov [ds:si], ah ; move ascii numeric to ds:si ;;;
mov [ds:si], dl ; 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
mov byte [ds:si], "$" ;;;
inc cx ; increase counter ;;;
inc si ; increase si ;;;
ret
print_string: ;;;
pusha ;;;
mov ah, 9 ;;;
mov dx, si ;;;
int 21h ;;;
popa ;;;
ret ;;;
DataWord dw 12345 ;;;
GreetString db "Hello World!", 13, 10, "$" ;;;