2012-04-29 2 views
2

У меня есть эта проблема с кодом, который преобразует число в ASCII 'number-text'. Однако код, кажется, зацикливается на опционном коде 'div'8086 сборка

;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 

Любая идея, почему это происходит? Я говорю «loop», потому что мой CPU находится на максимальном значении и не выполняет коды операций после div

* Обновлено. Спасибо, новый. Добавлен основной раздел, чтобы сделать его более читаемым (^. ^)

+0

Какую ценность бл есть? Вы никогда не назначаете его явно. – newgre

+0

да извините за это. я назначил его в основном разделе mov bl, 0x000A; base 10 call format_string; строка формата строки –

ответ

2

Проблема в том, что вы получаете исключение переполнения подразделения, потому что частное (в моем примере ниже 12345 div 10 = 1234 + остаток от 5) не подходит в 8 бит al (помните, что ah уже используется остатком?).

Каждый раз, когда либо частное, либо остальное не помещается в регистр назначения, вы получаете исключение переполнения подразделения. Это вызывает не только деление на 0.

Вы хотите сделать разделение 32/16 = 16: 16 вместо деления 16/8 = 8: 8.

Вот что работает в 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 
+0

Спасибо alot Alex = D Это, безусловно, помогло мне! Думаю, я все еще довольно смущен, почему это привело к «циклу»? –

+0

Если обработчик исключений по умолчанию (в BIOS или DOS) просто возвращается обратно (с IRET), вы получаете цикл: DIV-> обработчик исключений-> DIV-> обработчик исключений-> DIV -> ... Обработчик может «делать что-нибудь более разумное, потому что он« не знает », где эта инструкция (в какой программе или части системного программного обеспечения), и какими должны быть соответствующие действия в каждом случае. Это лучшее, что он может сделать. Однако вы можете переопределить обработчик и ввести в него логику, подходящую для вашей программы. –

+0

любой совет или справочный материал о том, как переопределить обработчик. это просто структура? –