【问题标题】:What's the corresponding prefix in arm assembly for "lock" in x86?x86中“lock”的arm组件对应的前缀是什么?
【发布时间】:2013-07-18 20:27:10
【问题描述】:

我有一个 x86 汇编代码:

unsigned int oldval;

__asm__ __volatile__ (
"movl   $1, %0  \n"
"lock xaddl %0, (%1)    \n"
: "=a" (oldval) :  "b" (n))l;

return oldval;

我想把它翻译成手臂组件。 arm 组件中是否有任何前缀与此处的“锁定”功能相同?

【问题讨论】:

  • 在 ARMv6 及更高版本上有 LDREX/STREX,它允许您尝试读取-更新-写入循环,直到没有其他操作修改加载和存储之间的引用内存位置。
  • 我会把它放在实际的响应中 - 听起来这是最好的方法。
  • ARM提供的通用同步概念是load-linked/store-conditional

标签: assembly locking arm


【解决方案1】:

我不了解 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 可能会溢出并为零,即使您未被允许获取锁。

【讨论】:

  • 我认为这一概念通常适用于从 CISC 到 RISC,因为只有 load-storelock 前缀仅对直接内存操作有意义。我猜PPC、MIPS等会有类似的翻译。
  • @artlessnoise:确实如此,请参阅我上面评论中的链接。
  • 刚刚在 godbolt.org 上运行了一个示例,生成的代码与您的示例非常相似(使用 aarch64 上的 stlxr 指令)。关于代码可能需要很长时间才能成功:在我看来,这种可能性也存在于带有锁前缀(其他一些线程一直持有/获取锁)的架构上。
【解决方案2】:

lock 前缀仅对内存访问有用。由于ARM不能对内存进行算术运算,所以没有直接对应的操作。如果您使用的是足够高的 ARM 内核版本,则可以使用dmbdsbisb 指令进行同步。否则,您将需要某种互斥锁。

【讨论】:

  • 谢谢。我已经更新了我的问题中的代码。我不知道如果我在这种情况下摆脱“锁定”会导致任何错误......
猜你喜欢
  • 2012-06-19
  • 2011-03-09
  • 2016-05-24
  • 2020-03-28
  • 2019-09-23
  • 2013-05-20
  • 2012-01-06
  • 2015-03-06
  • 1970-01-01
相关资源
最近更新 更多