当我尝试编译以下内容时,gcc 失败并显示
error: inconsistent operand constraints in an '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”,但我得到了同样的错误无论哪种方式。我错过了什么?
最佳答案
经过大量实验后,我意识到了这个问题以及为什么它在独立时没有导致错误:这是在代码中被编译到一个共享对象中,因此启用了“-fPIC”。这导致 gcc 在函数入口处使用 ebx
存储当前 eip
以便它可以通过函数的相对偏移量找到 GOT(在编译时已知)这样代码就可以与位置无关。因此,PIC 中使用 ebx
作为操作数的任何内联汇编都会产生这个完全不透明的错误。
关于c++ - 以下内联汇编有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21804470/