Reputation: 473
On my computer, the compiled executable omits executing "mov %2, %%ax" at the top of the loop
when "add %1, %%ax" uncommented.
Anyone to doublecheck or comment ?
#include <stdio.h>
int main() {
short unsigned result, low ,high;
low = 0;
high = 1;
__asm__ (
"movl $10, %%ecx \n\t"
"loop: mov %2, %%ax \n\t"
// "add %1, %%ax \n\t" // uncomment and result = 10
"mov %%ax, %0 \n\t"
"subl $1, %%ecx \n\t"
"jnz loop"
: "=r" (result)
: "r" (low) , "r" (high)
: "%ecx" ,"%eax" );
printf("%d\n", result);
return 0;
}
Follows the assembly generated
movl $1, %esi
xorl %edx, %edx
/APP
movl $10 ,%ecx
loop: mov %si, %ax
mov %dx, %bx
add %bx, %ax
mov %ax, %dx
subl $1, %ecx
jnz loop
/NO_APP
Thanks to Jester the solution :
: "=&r" (result) // early clober modifier
Upvotes: 3
Views: 737
Reputation: 58762
GCC inline assembly is advanced programming, with a lot of pitfalls. Make sure you actually need it, and can't replace it with standalone assembly module, or C code using intrinsics. or vector support.
If you insist on inline assembly, you should be prepared to at least look at the generated assembly code and try to figure out any mistakes from there. Obviously the compiler does not omit anything that you write into the asm block, it just substitutes the arguments. If you look at the generated code, you might see something like this:
add %dx, %ax
mov %ax, %dx
Apparently the compiler picked dx
for both argument 0
and 1
. It is allowed to do that, because by default it assumes that the input arguments are consumed before any outputs are written. To signal that this is not the case, you must use an early clobber modifier for your output operand, so it would look like "=&r"
.
PS: Even when inline assembly seems to work, it may have hidden problems that will bite you another day, when the compiler happens to make other choices. You should really avoid it.
Upvotes: 6