您的位置:首页 > 运维架构 > 网站架构

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

2012-11-22 14:09 2541 查看

LDREX 和 STREX

独占加载和存储寄存器。

语法

LDREX{[code]cond
}
Rt
, [
Rn
{, #
offset
}]

STREX{[code]cond
}
Rd
,
Rt
, [
Rn
{, #
offset
}]

LDREXB{[code]cond
}
Rt
, [
Rn
] 字节加载
[/code]
STREXB{[code]cond
}
Rd
,
Rt
, [
Rn
] 字节存储
[/code]
LDREXH{[code]cond
}
Rt
, [
Rn
] 半字加载
[/code]
STREXH{[code]cond
}
Rd
,
Rt
, [
Rn
] 半字存储
[/code]
LDREXD{[code]cond
}
Rt
,
Rt2
, [
Rn
] 双字加载
[/code]
STREXD{[code]cond
}
Rd
,
Rt
,
Rt2
, [
Rn
] 双字存储
[/code]
其中:

cond


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

[code]
Rd


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

[code]
Rt


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

[code]
Rt2


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

[code]
Rn


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

[code]
offset


为应用于 [code]
Rn
中的值的可选偏移量。[code]
offset

只可用于 Thumb-2 指令中。 如果省略 [code]
offset
,则认为偏移量为 0。

LDREX

[code]LDREX
可从内存加载数据。

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

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

STREX

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

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

中返回值 0。

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

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

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

限制

r15 不可用于 [code]
Rd
、[code]
Rt
、[code]
Rt2

或 [code]
Rn
中的任何一个。

对于 [code]STREX
Rd
一定不能与[code]
Rt
、[code]
Rt2

或[code]
Rn
为同一寄存器。

对于 ARM 指令:

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

[code]
Rt2
必须为[code]
R(t+1)


不允许使用 [code]
offset


对于 Thumb 指令:

r13 不可用于 [code]
Rd
、[code]
Rt
或[code]
Rt2

中的任何一个

对于 [code]LDREXD
Rt
和[code]
Rt2
不可为同一个寄存器

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

用法

利用 [code]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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: