arm架构的独占读写指令ldrex和strex的使用详解(原子操作和自旋锁实现的基本原理)

时间:2023-02-07 01:21:12



LDREX 和 STREX

独占加载和存储寄存器

语法

LDREX{cond} Rt, [Rn {, #offset}]
STREX{cond} Rd, Rt, [Rn {, #offset}]
LDREXB{cond} Rt, [Rn]          字节加载
STREXB{cond} Rd, Rt, [Rn]      字节存储
LDREXH{cond} Rt, [Rn]          半字加载
STREXH{cond} Rd, Rt, [Rn]      半字存储
LDREXD{cond} Rt, Rt2, [Rn]        双字加载
STREXD{cond} Rd, Rt, Rt2, [Rn]    双字存储

其中:

cond

是一个可选的条件代码(请参阅条件执行)。

Rd

是存放返回状态的目标寄存器。

Rt

是要加载或存储的寄存器。

Rt2

为进行双字加载或存储时要用到的第二个寄存器。

Rn

是内存地址所基于的寄存器。

offset

为应用于 Rn 中的值的可选偏移量。offset 只可用于 Thumb-2 指令中。 如果省略 offset,则认为偏移量为 0。

LDREX

LDREX 可从内存加载数据。

  • 如果物理地址有共享 TLB 属性,则 LDREX 会将该物理地址标记为由当前处理器独占访问,并且会清除该处理器对其他任何物理地址的任何独占访问标记。

  • 否则,会标记:执行处理器已经标记了一个物理地址,但访问尚未完毕。

STREX

STREX 可在一定条件下向内存存储数据。 条件具体如下:

  • 如果物理地址没有共享 TLB 属性,且执行处理器有一个已标记但尚未访问完毕的物理地址,那么将进行存储,清除该标记,并在Rd 中返回值 0

  • 如果物理地址没有共享 TLB 属性,且执行处理器也没有已标记但尚未访问完毕的物理地址,那么将不会进行存储,而会在Rd 中返回值 1

  • 如果物理地址有共享 TLB 属性,且已被标记为由执行处理器独占访问,那么将进行存储,清除该标记,并在Rd 中返回值 0

  • 如果物理地址有共享 TLB 属性,但没有标记为由执行处理器独占访问,那么不会进行存储,且会在Rd 中返回值 1

限制

r15 不可用于 RdRtRt2Rn 中的任何一个。

对于 STREXRd 一定不能与RtRt2Rn 为同一寄存器。

对于 ARM 指令:

  • Rt 必须是一个编号为偶数的寄存器,且不能为 r14

  • Rt2 必须为R(t+1)

  • 不允许使用 offset

对于 Thumb 指令:

  • r13 不可用于 RdRtRt2 中的任何一个

  • 对于 LDREXDRtRt2 不可为同一个寄存器

  • offset 的值可为 0-1020 范围内 4 的任何倍数。

用法

利用 LDREXSTREX 可在多个处理器和共享内存系统之前实现进程间通信。

出于性能方面的考虑,请将相应 LDREX 指令和 STREX 指令间的指令数控制到最少。

Note

STREX 指令中所用的地址必须要与近期执行次数最多的 LDREX 指令所用的地址相同。如果使用不同的地址,则STREX 指令的执行结果将不可预知。

体系结构

ARM LDREXSTREX 可用于 ARMv6 及更高版本中。

ARM LDREXBLDREXHLDREXDSTREXBSTREXDSTREXH 可用于 ARMv6K 及更高版本中。

所有这些 32 位 Thumb 指令均可用于 ARMv6T2 及更高版本,但 LDREXD STREXD 在 ARMv7-M 架构中不可用。

这些指令均无 16 位版本。

示例

    MOV r1, #0x1                ; load the ‘lock taken’ value
try
    LDREX r0, [LockAddr]        ; load the lock value
    CMP r0, #0                  ; is the lock free?
    STREXEQ r0, r1, [LockAddr]  ; try and claim the lock
    CMPEQ r0, #0                ; did this succeed?
    BNE try                     ; no – try again
    ....                        ; yes – we have the lock