以下内联程序集有什么问题

What is wrong with the following inline assembly?

本文关键字:什么 问题 程序集      更新时间:2023-10-16

当我尝试编译以下内容时,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",但无论哪种方式我都遇到相同的错误。我错过了什么?

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