我正在尝试编译另一个项目的代码,并且我继续获取Error: invalid instruction suffix for 'cmpxchg'
。错误指向的代码行是:
inline bool CAS(long *ptr, long oldv, long newv) {
unsigned char ret;
/* Note that sete sets a 'byte' not the word */
__asm__ __volatile__ (
" lock\n"
" cmpxchgq %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (newv), "m" (*ptr), "a" (oldv)
: "memory");
return ret;
}
我想知道是否有人知道错误的原因是什么,可能的解决方案是什么?
答案 0 :(得分:2)
正如评论家所说,问题是cmpxchg末尾的'q'。汇编器使用指令后缀字符来指示位宽,否则它将是不明确的。
对于64位目标,此代码使用gcc编译正常。你得到cmpxchgq指令的输出。
f0 48 0f b1 16 lock cmpxchg %rdx,(%rsi)
f0是LOCK前缀,48是REX.W前缀。真正的操作码是0f b1。
编译32位目标(gcc选项-m32)会导致后缀错误。
如果您需要此代码在32位计算机上运行,那么您在此处遇到了移植问题。 sizeof(long)在64位机器上为8,在32位机器上为4。 IF 并且它是一个很大的if,整个程序具有足够的弹性以容忍从8到4个字节的“长”,只需将'q'后缀更改为'l'即可逃脱(这是一个小写的L)。这为您提供了32位格式的'0f b1'指令:
f0 0f b1 16 lock cmpxchg %edx,(%esi)
如果没有,那么您可以尝试重写32位目标的程序集以使用CMPXCHG8B,这是一个具有不同寄存器触摸行为的不同指令。 CMPXCHG8B不是直接替代品!