Reputation: 305
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
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