pinglock
pinglock

Reputation: 1253

Why am I receiving a garbage value?

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

Answers (1)

rkhb
rkhb

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

Related Questions