问题
I have a x86 assembly code:
unsigned int oldval;
__asm__ __volatile__ (
"movl $1, %0 \n"
"lock xaddl %0, (%1) \n"
: "=a" (oldval) : "b" (n))l;
return oldval;
and I want to translate it into arm assembly. Is there any prefix in arm assembly that does the same thing as "lock" here?
回答1:
I don't know ARM, but from glossing over the manual, the following should approximate your atomic exchange-and-add:
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"
Unlike on x86, it would appear that this code could take arbitrarily long to succeed, but I'm not sure whether there are any guarantees that this will eventually succeed.
However, note that the ARM approach is safer, since the conditional store will success precisely when it should. By contrast, your x86 code (which looks like taken from a kernel spin lock?) just adds one to *n
and tests whether the original *n
was zero. If enough threads attempt this concurrently, then *n
can overflow and be zero even though you weren't allowed to take the lock.
回答2:
The lock
prefix is only useful for memory accesses. Since ARM can't do arithmetic on memory, there is not directly corresponding operation. If you're on a high-enough version of the ARM core, you can use the dmb
, dsb
and isb
instructions for synchronization. Otherwise, you'll need some sort of mutex.
来源:https://stackoverflow.com/questions/17733245/whats-the-corresponding-prefix-in-arm-assembly-for-lock-in-x86