ARM汇编ldr/str指令内存读写机制及多字节数据存储地址范围问题
ARM架构
str/ldr指令内存操作逻辑说明 1. 内存存储与加载的基础运行机制
str(存储)和ldr(加载)的访问宽度完全由指令后缀、操作的寄存器位宽决定,和操作的数值大小无关,核心运行逻辑如下:
- 存储流程:将寄存器中的数值按指定宽度拆分为N个字节,遵循当前CPU的端序规则,写入以目标地址为起始的N个连续内存单元
- 加载流程:从起始地址连续读取N个字节,遵循端序规则拼接为完整的数值,存入目标寄存器
- 常见宽度对应:
ldrb/strb:1字节(8位)宽度,仅操作起始地址1个内存单元ldrh/strh:2字节(16位半字)宽度,操作起始地址+0、+1共2个连续地址- 无后缀
ldr/str(32位ARM模式/操作32位W寄存器的AArch64模式):4字节(32位字)宽度,操作起始地址+0、+1、+2、+3共4个连续地址 ldrd/strd(32位ARM模式)/无后缀ldr/str(操作64位X寄存器的AArch64模式):8字节(64位双字)宽度,操作起始地址+0到+7共8个连续地址
存储32位字时,固定影响起始地址、起始地址+1、起始地址+2、起始地址+3这4个连续的内存地址。
2. 64位值存储与加载的具体行为
存储64位值20000000到0x0000b8f0的逻辑
没有任何版本的str指令会把64位数值存入单个内存地址,所有多字节存储指令都会拆分字节写入连续地址:
- 如果你使用的是32位宽度的
str指令,只会存储64位值的低32位,拆分4个字节写入0x0000b8f0~0x0000b8f3,高32位直接丢弃 - 如果你要完整存储64位值,32位ARM架构需要用
strd指令,AArch64架构需要用操作64位X寄存器的str指令,两类指令都会把64位值拆分为8个字节,按端序依次写入0x0000b8f0~0x0000b8f7的8个连续地址
从0x0000b8f0加载的逻辑
加载的字节数同样完全由指令本身决定,和地址本身无关:
- 仅
ldrb指令会只读取0x0000b8f0的单字节内容 - 32位宽度的
ldr指令会读取0x0000b8f0~0x0000b8f3的4个字节,拼接为32位数值存入寄存器 - 64位宽度的加载指令会读取0x0000b8f0~0x0000b8f7的8个字节,拼接为64位数值存入寄存器
Lifter内存模型实现注意点
- 端序适配:ARM架构默认使用小端序,低字节存储在低地址,高字节存储在高地址,部分场景支持配置大端序,建议预留端序适配开关
- 对齐检查:ARM默认要求内存访问地址对齐到访问宽度的整数倍,非对齐访问在部分架构版本下会触发数据中止异常,可根据你要适配的ARM版本选择模拟对齐异常,或者实现非对齐访问逻辑
内容的提问来源于stack exchange,提问作者hany erfan
相关产品推荐
相关产品推荐

