ldp
(Load Pair) 是 ARM 架构中的一种高效加载指令,用于同时从内存加载两个寄存器。
基本语法
ldp <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
ldp <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
ldp <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
三种寻址模式
-
后变址模式:
ldp x0, x1, [x2], #16 // 从x2地址加载x0和x1,然后x2 += 16
-
前变址模式:
ldp x0, x1, [x2, #16]! // x2 += 16,然后从新x2地址加载x0和x1
-
偏移模式:
ldp x0, x1, [x2, #16] // 从x2+16地址加载x0和x1,不改变x2
关键特点
- 双字加载:同时加载两个64位寄存器(或两个32位使用w寄存器)
- 对齐要求:地址通常需要8字节对齐(加载64位)或4字节对齐(加载32位)
- 立即数范围:偏移量必须是8的倍数且在-512到504范围内(对于64位)
- 常用场景:函数开场/退场时保存恢复寄存器对
典型应用
1. 函数开场保存寄存器
stp x29, x30, [sp, #-16]! // 保存FP和LR到栈,并调整SP
2. 函数退场恢复寄存器
ldp x29, x30, [sp], #16 // 从栈恢复FP和LR,并调整SP
3. 高效内存拷贝
loop:
ldp x0, x1, [x2], #16 // 从x2加载16字节到x0和x1
stp x0, x1, [x3], #16 // 存储x0和x1到x3
subs x4, x4, #16 // 减少计数器
b.gt loop // 循环继续
与相关指令对比
指令 | 功能 | 特点 |
---|---|---|
ldp |
加载寄存器对 | 高效加载两个相邻寄存器 |
ldr |
加载单个寄存器 | 通用加载指令 |
ldnp |
非临时加载 | 不缓存预取 |
stp |
存储寄存器对 |
ldp 的存储对应指令 |
注意事项
- 使用前确保内存地址正确对齐
- 注意后变址和前变址模式对基址寄存器的影响
- 在堆栈操作中注意栈指针的正确维护
- 立即数偏移必须在合法范围内
ldp
是 ARM 架构中优化内存访问性能的重要指令,特别适合处理寄存器对和批量数据加载场景。