Reputation: 1253
I'm very new to Assembly and cannot find the source of this bug after a good amount of debugging.
I have the following Assembly function. The goal is to calculate the value of x. All input variables are of type short and have values:
a = 3
b = 1
c = 1
d = 1
e = -2
f = 5
The function is:
void calculate_x()
{
__asm
{
mov ax, c
imul e
mov numer, ax
mov ax, b
imul f
sub numer, ax
mov ax, a
imul e
mov denom, ax
mov ax, b
imul d
sub denom, ax
mov bx, numer
idiv bx
mov x, ax
}
}
I'm getting a result of x = 0
but it should be x = 1
.
When I set breakpoints, the problem seems to lie in third to last line mov bx, numer
. This results in bx
receiving a garbage value but it should receive a value of -7
.
Why is bx
receiving a garbage value?
Upvotes: 0
Views: 415
Reputation: 14409
Not BX
receives the garbage, AX
does it. You calculate denom in memory but forget to reload it into DX:AX as the dividend for idiv
.
Note that you need a valid value both in DX
and AX
for IDIV
:
#include <stdio.h>
short a = 3;
short b = 1;
short c = 1;
short d = 1;
short e = -2;
short f = 5;
short x, numer, denom;
// (a*e - b*d) / (c*e - b*f)
void calculate_x()
{
__asm
{
mov ax, c
imul e
mov numer, ax
mov ax, b
imul f
sub numer, ax
mov ax, a
imul e
mov denom, ax
mov ax, b
imul d
sub denom, ax
movsx eax, denom
cwd
mov bx, numer
idiv bx
mov x, ax
}
}
int main()
{
puts ("(a*e - b*d) / (c*e - b*f)");
calculate_x();
printf("%d / %d = %d", denom, numer, x);
// note that numerator and denominator are misnamed.
// we really are calculating denom / numer
return 0;
}
Upvotes: 1