Reputation: 21
When I try to compile the following, gcc fails with
error: inconsistent operand constraints in an 'asm'"
Unfortunately, when I pull the function into a standalone file it compiles fine, so I'm really not sure what the issue is. The idea behind the function is to provide a wrapper around a function written in assembly that will enforce the expected calling convention regardless of the target platform.
int wrap(int(*asmfn)(int,int,int,int), int param1, int param2, int param3, int param4) {
int x;
asm ( "push %1;" //save the input operand so it's not clobbered
"push %5;" //push the params RTL
"push %4;"
"push %3;"
"push %2;"
"call *%1;" //call the function
"pop %2;" //caller cleanup / restore the param operands so they are not clobbered
"pop %3;"
"pop %4;"
"pop %5;"
"pop %1;" //restore the other operand so it's not clobbered
"mov %%eax, %0;" //save the retval to a local
: "=X" (x)
: "c" (asmfn), "d" (param1), "b" (param2), "S" (param3), "D" (param4)
: "cc", "memory", "%eax" );
return x;
}
I've tried constraining the output operand into either memory only or a register, or even constraining it specifically into eax
and dropping "%eax" from the clobber list, but I get the same error either way. What am I missing?
Upvotes: 1
Views: 505
Reputation: 21
After much experimentation I realized the issue and why it wasn't causing an error when standalone: this was in code being compiled into a shared object, and hence "-fPIC" was enabled. This causes gcc to use ebx
to store current eip
on entrance to a function so it can find the GOT via a relative offset from the function (which is known at compile time) so that the code can be position independent. As a result, any inline assembly in PIC that uses ebx
as an operand will give this completely opaque error.
Upvotes: 1