Janus Gowda
Janus Gowda

Reputation: 305

Inline assembly in C not working properly

I'm trying to learn how to use inline assembly in C code. I have created a small program that should add two integers:

int main(){
        int a=1;
        int b=2;
        asm(    "movl %0, %%r8d;"
                "movl %1, %%r9d;"
                "addl %%r8d, %%r9d;"
                "movl %%r9d, %1;"
                : "=r"  (a)
                : "r"   (b)
                :"%r8","%r9" );
        printf("a=%d\n",a);
        return 0;
}

The aim was to load a and b into the registers %r8 and %r9, add them, and then put the output back in a. However this program prints a=2 instead a=3. I'm not sure if the problem is in the inline technique or in the assembly itself.

Upvotes: 3

Views: 163

Answers (1)

user149341
user149341

Reputation:

There are two issues here:

First: The "=r" constraint you use for the output operand a indicates to the compiler that the operand is write-only — it is allowed to assume that the initial value is not needed. This is definitely not the case for your code! Change the qualifier to "+r" to let the compiler know that the initial value is important.

Second: You are moving the result to the wrong register! The target %1 of the last movl is the register corresponding to b, not a. You want %0.

Fixed:

asm(
    "movl %0, %%r8d;"
    "movl %1, %%r9d;"
    "addl %%r8d, %%r9d;"
    "movl %%r9d, %0;"
    : "+r" (a)
    : "r"  (b)
    : "%r8", "%r9"
);

Upvotes: 4

Related Questions