Reputation: 131
So I'm building a simple 8086 program that allows the user to input 2 2-digit numbers and an operator and perform an operation. If the operator is "+" it adds them and if it's "*" it multiplies them and prints the result on screen:
.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
The problem lies within the printing. If the number is less than 100 it jumps to only print out the two digits. However if it's greater of equal than 100 it divides the number by 100, prints out the result as the first of the 3 digits and puts the remainder in AX
so it can continue with printing out the two digits. However when it continues I get the error message saying:
divide error - overflow.
to manually process this error,
change address of INT 0 in interrupt vector table.
Can anyone help?
Upvotes: 2
Views: 285
Reputation: 9899
Dvocifren: mov bx, 10 div bx
When your code jumps here, DX
happens to be zero (Only if the requested operation was the multiplication!), which is good as you need it for this WORD-sized division.
BUT when your program falls through, DX
is no longer zero. DL
holds the character that you printed with DOS.
Solve it by using the BYTE-sized division instead, or else write:
Dvocifren:
XOR DX, DX
mov bx, 10
div bx
You might not realize this but the multiplication of 2 2-digit numbers can lead to a 4-digit result, where the sum of 2 2-digit numbers can only produce a 3-digit result. As a consequence your program will fail on e.g. 32 * 32 = 1024 (4 digits!)
Because of what the task demands, I suggest you use BYTE-sized multiplication and BYTE-sized division everywhere.
Next code is able to display the 4-digits result:
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
Upvotes: 3