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
只可用于 Thumb-2 指令中。 如果省略offset
,则认为偏移量为 0。offset
LDREX
可从内存加载数据。
-
如果物理地址有共享 TLB 属性,则
LDREX
会将该物理地址标记为由当前处理器独占访问,并且会清除该处理器对其他任何物理地址的任何独占访问标记。 -
否则,会标记:执行处理器已经标记了一个物理地址,但访问尚未完毕。
STREX
可在一定条件下向内存存储数据。 条件具体如下:
-
如果物理地址没有共享 TLB 属性,且执行处理器有一个已标记但尚未访问完毕的物理地址,那么将会进行存储,清除该标记,并在
中返回值 0。Rd
-
如果物理地址没有共享 TLB 属性,且执行处理器也没有已标记但尚未访问完毕的物理地址,那么将不会进行存储,而会在
中返回值 1。Rd
-
如果物理地址有共享 TLB 属性,且已被标记为由执行处理器独占访问,那么将进行存储,清除该标记,并在
中返回值 0。Rd
-
如果物理地址有共享 TLB 属性,但没有标记为由执行处理器独占访问,那么不会进行存储,且会在
中返回值 1。Rd
r15 不可用于
、Rd
、Rt
或 Rt2
中的任何一个。Rn
对于 STREX
,
一定不能与Rd
、Rt
或Rt2
为同一寄存器。Rn
对于 ARM 指令:
-
必须是一个编号为偶数的寄存器,且不能为 r14Rt
-
必须为Rt2
R(t+1)
-
不允许使用
。offset
对于 Thumb 指令:
-
r13 不可用于
、Rd
或Rt
中的任何一个Rt2
-
对于
LDREXD
,
和Rt
不可为同一个寄存器Rt2
-
的值可为 0-1020 范围内 4 的任何倍数。offset
利用 LDREX
和 STREX
可在多个处理器和共享内存系统之前实现进程间通信。
出于性能方面的考虑,请将相应 LDREX
指令和 STREX
指令间的指令数控制到最少。
Note
STREX
指令中所用的地址必须要与近期执行次数最多的 LDREX
指令所用的地址相同。如果使用不同的地址,则STREX
指令的执行结果将不可预知。
ARM LDREX
和 STREX
可用于 ARMv6 及更高版本中。
ARM LDREXB
、LDREXH
、LDREXD
、STREXB
、STREXD
和STREXH
可用于 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