我试图为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 寄存器但来自堆栈!
我做错了什么?
答案 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?