Reputation: 2921
I'm trying to compute the expression A * B + ( A + B ) / ( A - B )
, where A and B are integers input by the user. I'm using the ALong32 library on a linux kernel.
%include "along32.inc"
section .data
msg1 db 'Enter A: ', 0
msg2 db 'Enter B: ', 0
msg3 db 'Result: ' , 0
err db 'Error: cannot divide by 0', 0
A resb 4
B resb 4
section .text
global main
main:
mov edx, msg1
call WriteString
call ReadInt
mov [A], eax ; move the input into A
mov edx, msg2
call WriteString
call ReadInt ; move the next number into eax
cmp eax, [A] ; compare A and eax (B)
je error ; if A and B are equal, error
mov [B], eax ; move eax into B
mov eax, [A]
add eax, [B]
mov ebx, eax ; ebx = A + B
mov eax, [A]
sub eax, [B] ; eax = A - B
div ebx
mov ebx, eax ; ebx = (A + B) / (A - B)
mov ecx, [B]
mov eax, [A]
mul ecx
mov ecx, eax ; ecx = A * B
add eax, ecx ; eax = A * B + (A + B) / (A - B)
mov edx, msg3
call WriteString
call WriteInt
jmp end
error:
mov edx, err
call WriteString
jmp end
end:
mov eax, 1
int 0x80
I feel like I've commented what I'm doing pretty well, but I'll explain what I'm doing more in depth if that's needed.
When I run this code, after I input both numbers, I get a floating point exception
, and the program exits.
Why is this happening? I check for division by 0.
Upvotes: 4
Views: 6205
Reputation: 39166
I see 2 problems with your program.
The div ebx
instruction uses EDX:EAX as the dividend and you fail to set it up. Just insert an xor edx,edx
xor edx, edx ; <--------------------------------- Add this !
div ebx
mov ebx, eax ; ebx = (A + B) / (A - B)
After the division you store the quotient in EBX but you never pick it up again to display the result!
mov ecx, [B]
mov eax, [A]
mul ecx
mov ecx, eax ; ecx = A * B
mov eax, ebx ; <--------------------------------- Add this !
add eax, ecx ; eax = A * B + (A + B) / (A - B)
The 2nd issue can be solved in a shorter way:
mov ecx, [B]
mov eax, [A]
mul ecx
add eax, ebx ; eax = A * B + (A + B) / (A - B)
EDIT (late catch, sorry)
I check for division by 0.
A * B + ( A + B ) / ( A - B )
You've based your check on the divider being (A - B)
and thus exit if A
is equal to B
.
Correct, but the program code erroneously calculates (A - B) / (A + B)
and so is using (A + B)
as the divider!
This is my version of calculating A * B + ( A + B ) / ( A - B )
:
mov ebx, [A]
sub ebx, [B] ; EBX = (A - B)
jz error ; Guard against division by zero!
mov eax, [A]
add eax, [B] ; EAX = (A + B)
xor edx, edx ; EDX:EAX = (A + B)
div ebx ; EAX = (A + B) / (A - B)
mov ebx, [A]
imul ebx, [B] ; EBX = A * B
add eax, ebx ; EAX = A * B + (A + B) / (A - B)
Upvotes: 7