Распечатка трехзначного числа дает мне переполнение - PullRequest
0 голосов
/ 27 ноября 2018

Итак, я создаю простую программу 8086, которая позволяет пользователю вводить 2 2-значных номера и оператора и выполнять операции.Если оператор «+», он добавляет их, а если «*», он умножает их и печатает результат на экране:

.model small
.stack 100
.data

  x db ?
  y db ?
  rez dw ?

.code

    mov ax, data
    mov ds, ax
    mov es, ax

    mov ah, 1
    int 21h
    sub al, 48

    mov bl, 10
    mul bl

    mov x, al

    mov ah, 1
    int 21h
    sub al, 48

    add x, al

    mov ah, 1
    int 21h
    sub al, 48

    mov bl, 10
    mul bl

    mov y, al

    mov ah, 1
    int 21h
    sub al, 48

    add y, al

    mov ah, 1
    int 21h

    cmp al, 43
    jne Multiply

    mov al, x
    mov bl, y
    add al, bl
    mov ah, 0
    mov rez, ax
    jmp Print

Multiply:
    mov al, x
    mov ah, 0

    mov bl, y
    mov bh, 0
    mul bx

    mov rez, ax

Print:

    mov ax, rez
    cmp ax, 100
    jl Dvocifren
    mov bx, 100
    div bx
    mov cx, dx
    mov dl, al
    add dl, 48
    mov ah, 2
    int 21h
    mov ax, cx
    mov rez, ax

Dvocifren:
    mov bx, 10
    div bx

    mov cl, dl

    mov dl, al
    add dl, 48
    mov ah, 2
    int 21h

    mov dl, cl
    add dl, 48
    int 21h

Проблема заключается в печати.Если число меньше 100, оно переходит к распечатке только двух цифр.Однако, если он больше 100, он делит число на 100, выводит результат в виде первой из 3 цифр и помещает остаток в AX, чтобы можно было продолжить печать двух цифр.Однако, когда это продолжается, я получаю сообщение об ошибке:

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

Кто-нибудь может помочь?

1 Ответ

0 голосов
/ 28 ноября 2018
Dvocifren:
    mov bx, 10
    div bx

Когда ваш код переходит сюда, DX оказывается равным нулю ( Только если запрошенная операция была умножением! ), что хорошо, если вам нужнодля этого деления размера WORD.

НО когда ваша программа проваливается, DX больше не равен нулю.DL содержит символ, который вы напечатали в DOS.

Решите его, используя вместо этого деление по размеру BYTE, или напишите:

Dvocifren:
    XOR DX, DX
    mov bx, 10
    div bx

Возможно, вы этого не пойметено умножение 2-значных 2-значных чисел может привести к результату 4-значное , при котором сумма 2-значных 2-значных чисел может дать только 3-значное результат.Как следствие, ваша программа не будет работать, например, 32 * 32 = 1024 (4 цифры!)


. В связи с тем, что требуется для этой задачи, я предлагаю вам использовать умножение в байтах и ​​деление в байтах везде.
Следующий код может отображать 4-значный результат:

Multiply:
 mov al, x
 mov bl, y
 mul bl
 mov rez, ax

Print:
 mov ax, rez
 cmp ax, 100
 jl Dvocifren

 mov bl, 100
 div bl
 mov cl, ah   ;Remainder [0,99]
 mov ch, 0
 push cx      ;Preserve the lowest 2 digits

 mov ah, 0    ;Quotient [0,98]
 mov bl, 10
 div bl
 mov cl, ah   ;Remainder [0,9]
 mov dl, al   ;Quotient  [0,9]
 add dl, 48
 mov ah, 02h
 int 21h
 mov dl, cl
 add dl, 48
 mov ah, 02h
 int 21h

 pop ax       ;Restore lowest 2 digits

Dvocifren:
 mov bl, 10
 div bl
 mov cl, ah   ;Remainder [0,9]
 mov dl, al   ;Quotient  [0,9]
 add dl, 48
 mov ah, 02h
 int 21h
 mov dl, cl
 add dl, 48
 mov ah, 02h
 int 21h
...