gcc内联asm bug - 参数被忽略

时间:2016-01-22 22:10:37

标签: gcc assembly x86

我试图为BTS指令编写一个小包装函数。所以不是显而易见的:

bool bts( volatile uint32_t* dst, int idx ) {
  uint32_t mask = 1 << idx;
  bool ret = !!(dst & mask);
  dst |= mask;
  return ret;
}

我写了这个:

bool bts( volatile uint32_t* dst, int idx ) {
  bool ret;
  asm( "xor %1, %1\n\t"
       "bts %2, %0\n\t"
       "adc %1, %1"
       : "+m"(*dst), "=r"(ret) : "Ir"(idx) : "cc","memory" );
  return ret;
}

这在构建优化代码时表现良好,但在构建非优化代码时, idx 始终为0.从生成的asm中,看起来它没有采用它来自 rdx 寄存器但来自堆栈!

我做错了什么?

1 个答案:

答案 0 :(得分:4)

事实上,GCC首先将所有数据复制到堆栈中。这样做是为了获得更好的调试体验(当使用-O0进行编译时,变量不应该是&#34;优化出来&#34;)。但看起来问题的原因是你早期的问题%1,即GCC假设您只在读取输入后写入输出并为%1%2分配共享寄存器( al和eax resp。用于我试过的版本。

您可以使用"=&r"约束而不是"=r"来阻止这种情况发生。

另见When to use earlyclobber constraint in extended GCC inline assembly?