Ошибка «Ошибка разделения -переполнение» в 8086 emu

#assembly #x86-16 #emu8086

#сборка #x86-16 #emu8086

Вопрос:

Напишите программу на языке ассемблера, чтобы добавить все элементы таблицы, которых всего от 50 до 100. Отобразите результат в виде десятичного значения.

Мой сольн:

 .model small 
.stack 64
.data
    table db 0, 25, 50, 75, 100, 125, 150, 175, 200 
    ten db 10
.code
    main proc
        mov dx, @data
        mov ds, ax
        lea si, table
        mov dx, 0
        mov bx, 0
        mov cx, 9
    l2: mov ax, [si]   
        cmp ax,   50
        jb l1
        cmp ax, 150
        ja l1
        add ax, dx
        mov dx, ax
    l1: inc si
        loop l2
    l3: mov dx, 0
        div ten
        add dx, 30H
        push dx
        inc bx
        cmp ax, 0
        jne l3
        mov ah, 02H
    l4: pop dx
        int 21h
        dec bx
        jnz l4 
        mov ax, 4c00H
        int 21H
    main endp 
end main
 

Он показывает ошибку ->> ошибка разделения — переполнение.чтобы вручную обработать эту ошибку, измените адрес INT 0 в таблице векторов прерываний.

Каково решение для этого? Спасибо!

Комментарии:

1. Ваша таблица состоит из байтов, но вы загружаете слова.

2. @Jester хорошо, я изменил db на dw для обоих данных. Его отображение 0 в качестве вывода, почему?

Ответ №1:

ошибка разделения — overflow.to обработайте эту ошибку вручную, измените адрес INT 0 в таблице векторов прерываний.

Очень примечательно, что emu8086 сразу же сделал такое предложение!
Решение состоит в том, чтобы избежать ошибки деления (ошибка, которую вы получаете, потому что частное от деления не может поместиться в предназначенный регистр AL )!
Используемое вами деление размером в байт div ten работает AX и оставляет частное, AL а остаток AH .

Некоторые ошибки (могут) способствовать возникновению проблемы:

  • Вы загружаете слова из таблицы, заполненной байтами ( mov ax, [si] ).
  • Вы допускаете больший дивиденд, чем указано в задаче ( cmp ax, 150 ).

Это будет работать:

     xor  dx, dx
    mov  cx, 9
l2: mov  al, [si]
    mov  ah, 0
    cmp  al, 50
    jb   l1
    cmp  al, 100
    ja   l1
    add  dx, ax
l1: inc  si
    loop l2

; At the end of the previous loop, `CX` is zero.
; We can use that for a digit counter instead of `BX`.
; Next division scheme will work fine for dividends up to 2550.

    mov  ax, dx     ; -> AX = 50   75   100 = 225
l3: div  ten        ; AX / 10  -> Quotient is in AL
    add  ah, 30h    ; Remainder is in AH
    push ax
    inc  cx
    mov  ah, 0
    cmp  al, 0
    jne  l3

l4: pop  dx
    mov  dl, dh
    mov  ah, 02h    ; DOS.PrintChar
    int  21h
    dec  cx
    jnz  l4 
 

Комментарии:

1. @SachinBhusal Вы можете сохранить db байтовые данные. Смотрите мой отредактированный ответ.

2. Большое вам спасибо!