我发现LDREX
和STREX
可能是要使用的那些。但是它们是两条指令(因此不提供xchgl
的原子性)。我要原子交换的值是一个32位值。
能否以提供32位值的原子交换的方式使用LDREX
和STREX
或使用其他方式来实现该值(前提是它可以在armv7l或更高版本上运行)?
通常,我会选择gcc的atomic builtins或更新的版本(相当于C ++ 11)builtin functions
这样的原子操作。但是在这种情况下,我必须在C中使用内联汇编(以将基于x86的futex实现移植到ARM体系结构)。谢谢!
最佳答案
在ARM指令集中,没有原子交换指令。而是使用ldrex
和strex
以及类似的代码:
@ exchange r0 and [r1]
ldrex r2,[r1]
strex r3, r0,[r1]
mov r0,r2
如果在
[r1]
和ldrex
之间修改了strex
或由于某些其他原因不能保证交换是原子交换,则在r3
中返回1,并且不执行存储。如果序列是原子序列,则返回0。因此,通过循环执行此代码段直到获得r3
零,您最终可以进行原子交换操作。实际上,这就是gcc和clang实现相应内在函数的方式。将-S
传递给编译器以观察其作用。
关于gcc - 与Intel的xchgl等效的ARM指令是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43640556/