我有一个x86汇编代码:
unsigned int oldval;
__asm__ __volatile__ (
"movl $1, %0 \n"
"lock xaddl %0, (%1) \n"
: "=a" (oldval) : "b" (n))l;
return oldval;
我想把它翻译成手臂组装。臂组件中是否有任何与“锁定”相同的前缀?
答案 0 :(得分:4)
我不了解ARM,但是通过对手册的修改,以下内容应该接近您的原子交换 - 并且添加:
foo:
LDREX R1, [R0] ; R0 is "n", load linked
ADD R2, R1, 1 ; R2 = R1 + 1
STREX R3, R2, [R0] ; store conditionally, R3 = 0 if and only if success
CBNZ R3, foo ; on failure, try again
;; now return R1 to "oldval"
与x86不同,看起来这段代码可能需要很长时间才能成功,但我不确定是否有任何保证最终会成功。
但请注意,ARM方法更安全,因为条件存储将在应有的时候成功。相比之下,您的x86代码(看起来像是从内核自旋锁中获取?)只是向*n
添加一个,并测试原始*n
是否为零。如果有足够的线程同时尝试此操作,那么即使您不允许锁定,*n
也会溢出并为零。
答案 1 :(得分:1)
lock
前缀仅对内存访问有用。由于ARM无法对内存进行算术运算,因此没有直接对应的操作。如果您使用的是ARM内核的高版本,则可以使用dmb
,dsb
和isb
指令进行同步。否则,你需要某种互斥量。