2

数値をASCII'number-text'に変換する以下のコードでこの問題が発生します。ただし、コードは「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に感謝します。読みやすくするためにメインセクションを追加しました(^。^)

4

1 に答える 1

2

問題は、商(以下の例では12345 div 10 = 1234 + 5の余り)がの8ビットに収まらないため(余りですでに使用されているalことを覚えていますか?)、除算オーバーフロー例外が発生することです。ah

商または剰余のいずれかが宛先レジスタに収まらないたびに、除算オーバーフロー例外が発生します。それを引き起こすのは0による除算だけではありません。

16/8 = 8:8除算ではなく、32/16 = 16:16除算を実行します。

これが私の変更(としてマークされている;;;)でDOSで機能するものです:

; 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, "$" ;;;

それは印刷します:

Hello World!
54321
于 2012-04-29T11:21:57.240 に答える