C++ 以下内联程序集有什么问题?
当我尝试编译以下代码时,gcc失败了 错误:“asm”中的操作数约束不一致 不幸的是,当我把函数拉到一个独立的文件中时,它编译得很好,所以我真的不确定问题出在哪里。函数背后的想法是为一个用汇编编写的函数提供一个包装器,它将强制执行预期的调用约定,而不管目标平台是什么C++ 以下内联程序集有什么问题?,c++,g++,inline-assembly,C++,G++,Inline Assembly,当我尝试编译以下代码时,gcc失败了 错误:“asm”中的操作数约束不一致 不幸的是,当我把函数拉到一个独立的文件中时,它编译得很好,所以我真的不确定问题出在哪里。函数背后的想法是为一个用汇编编写的函数提供一个包装器,它将强制执行预期的调用约定,而不管目标平台是什么 int wrap(int(*asmfn)(int,int,int,int), int param1, int param2, int param3, int param4) { int x; asm ( "push
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
中并删除“%eax”“从clobber列表中,我得到了同样的错误。我遗漏了什么?经过多次实验,我意识到了这个问题,以及为什么它在独立运行时不会导致错误:这是在编译到共享对象的代码中,因此启用了“-fPIC”。这导致gcc在函数入口使用ebx存储当前的eip,这样它就可以通过函数的相对偏移量(在编译时已知)找到GOT,这样代码就可以独立于位置。因此,PIC中使用ebx
作为操作数的任何内联程序集都会产生这个完全不透明的错误。@KarolyHorvath有一个原因,但无论如何,我仍然会得到这个错误。我更新了这个问题,使它看起来不那么不寻常。我认为它是反对的,因为您正在使用所有可用的寄存器,然后说您正在使用%eax
。您列表中提到的唯一寄存器是%esp
和%ebp
,因此%0可能会存储在%eax
中-因此,您也不能对%eax
@matstpeterson进行重击,我认为这可能是一个问题,这就是为什么我在问题的最后一段尝试了解决方法,但仍然给出了相同的错误。作为一个实验,我也尝试过完全删除掉所有内容(虽然这显然会导致错误的代码),但仍然出现了错误。啊哈,发现了问题,但在8小时内无法将其作为答案发布。。。希望我会记得回来发布它,这样其他有这个问题的人就可以找到答案。发出一堆“指令要求:不是64位模式”的错误消息,在32位模式下确实如此。可能在推送/弹出指令中需要不同的限定符?