当我尝试编译以下内容时,gcc失败并带有
错误:'asm'“
中的操作数限制不一致
不幸的是,当我将该函数拉入独立文件时,它编译得很好,所以我真的不确定问题是什么。该函数背后的想法是提供一个围绕用汇编编写的函数的包装器,它将强制执行预期的调用约定,而不管目标平台如何。
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;
}
我尝试将输出操作数限制在仅内存或寄存器中,或者甚至将其专门限制为eax
并从clobber列表中删除“%eax”,但无论如何我都会得到相同的错误。我错过了什么?
答案 0 :(得分:1)
经过多次实验后,我意识到了这个问题以及为什么它在独立时没有导致错误:这是在代码被编译成共享对象时,因此启用了“-fPIC”。这会导致gcc使用ebx
在函数入口处存储当前eip
,这样它就可以通过函数的相对偏移量(在编译时已知)找到GOT,这样代码就可以了职位独立。因此,PIC中使用ebx
作为操作数的任何内联汇编都会产生完全不透明的错误。