Addition function in Windows X86 via inline asm lines in C code

Viewed 72

Can someone explain what I'm doing wrong here:

int MachineAdder(int a, int b)
{
    int OUT = 0;        /* Assign a pointer (&OUT) and write initial data (0) */

    __asm ("mov %[dst], %[src]" /* Machine instruction to execute, separated by commas.*/
      : [dst] "=r" (OUT)
      : [src] "r" (a)
    );
    __asm ("add %[dst], %[src]" /* Machine instruction to execute, separated by commas.*/
      : [dst] "=r" (OUT)
      : [src] "r" (b)
    );

    return OUT; /* Return the value a+b */
}

In my main() function, I call:

printf("0+0 = %d\n", MachineAdder(0,0));
printf("0+1 = %d\n", MachineAdder(0,1));
printf("1+0 = %d\n", MachineAdder(1,0));
printf("1+1 = %d\n", MachineAdder(1,1));
printf("2+1 = %d\n", MachineAdder(2,1));
printf("1+2 = %d\n", MachineAdder(1,2));

In my output, it reads "0 2 0 2 2 4" (whereas I'd expect "0 1 1 2 3 3").

Thanks! Googling answers was messy because some machine instructions seem to be back to front, while others talk about registers but I don't know which register is which or how to use them.

EDIT: Working solution found. There were two errors: src and dst were the wrong way around, and I had never heard of the "+r" string, used for inout parameters. Here's the fixed version:

int MachineAdder(int a, int b)
{
    int OUT = 0;        /* Assign a pointer (&OUT) and write initial data (0) */

    __asm ("mov %[src], %[dst]" /* Machine instruction to execute, separated by commas.*/
      : [dst] "=r" (OUT)
      : [src] "r" (a)
    );
    __asm ("add %[src], %[dst]" /* Machine instruction to execute, separated by commas.*/
      : [dst] "+r" (OUT)
      : [src] "r" (b)
    );

    return OUT; /* Return the value a+b */
}

Thanks all!

1 Answers

This is because, in the output operands, = mark doesn't guarantee that the location has the existing value while + mark does.

Extended Asm (Using the GNU Compiler Collection (GCC)) says:

Output constraints must begin with either ‘=’ (a variable overwriting an existing value) or ‘+’ (when reading and writing). When using ‘=’, do not assume the location contains the existing value on entry to the asm, except when the operand is tied to an input

Related