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

标签 c++ g++ inline-assembly

当我尝试编译以下内容时,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/

相关文章:

c++ - OpenCV 2.3 编译问题 - undefined reference - Ubuntu 11.10

rust - 为什么 Rust 堆栈框架如此之大?

c++ - 在 SSE 寄存器中存储常量(GCC、C++)

c++ - 当 bWaitAll 为 TRUE 时,WaitForMultipleObjects 返回值

c++ - 在 C++ 中初始化静态常量数组的特定元素

c++ - 在 C++ 中省略 return 语句

gcc - 内联汇编与C代码混合-如何保护寄存器并最大程度地减少内存访问

c++ - 可以将 .Net String 交给 fn(const char16_t* str) w/o 复制吗?

c++ - 当 -std=c++17 在编译器输出中时,编译器请求通过使用 -std++17 标志为 std::variant 启用 c++17 支持

java - 在 Java 中通过 UDP 发送 C++ 结构