以下内联汇编有什么问题?

时间:2014-02-15 22:23:45

标签: 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 %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”,但无论如何我都会得到相同的错误。我错过了什么?

1 个答案:

答案 0 :(得分:1)

经过多次实验后,我意识到了这个问题以及为什么它在独立时没有导致错误:这是在代码被编译成共享对象时,因此启用了“-fPIC”。这会导致gcc使用ebx在函数入口处存储当前eip,这样它就可以通过函数的相对偏移量(在编译时已知)找到GOT,这样代码就可以了职位独立。因此,PIC中使用ebx作为操作数的任何内联汇编都会产生完全不透明的错误。