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?
%eax
. The only register mentioned in your list is%esp
and%ebp
, so %0 will probably be stored in%eax
- hence, you can't also clobber%eax
. – Mats Petersson