1. ARM内存访问指令基础解析
在嵌入式系统开发中,处理器与内存之间的数据交换是最基础也是最频繁的操作。ARM架构作为嵌入式领域的主流选择,其内存访问指令的设计直接影响着系统性能和能效表现。LDR(Load Register)和STR(Store Register)这对指令构成了ARM内存操作的核心,它们支持从字节到双字的各种数据类型传输,并通过多种寻址模式满足不同场景的需求。
1.1 内存访问的基本原理
现代处理器采用"加载-存储"架构,这意味着所有数据处理操作都必须在寄存器中完成,而内存仅用于数据存储。这种设计带来了几个关键特性:
- 数据必须先从内存加载到寄存器才能参与运算
- 运算结果必须显式存储回内存才会被保存
- 内存访问速度远低于寄存器操作(通常相差数十倍)
ARM处理器的寄存器文件包含16个32位通用寄存器(r0-r15),其中r15作为程序计数器PC使用。LDR指令将数据从内存加载到目标寄存器,STR指令则将寄存器值存储到内存地址。一个典型的数据处理流程如下:
assembly复制LDR r0, [r1] ; 将r1指向的内存数据加载到r0
ADD r0, r0, #5 ; 对r0中的数据进行运算
STR r0, [r1] ; 将结果存回r1指向的内存
1.2 数据类型支持
ARM指令集支持多种数据宽度的内存访问,通过指令后缀指定:
| 类型后缀 | 数据宽度 | 说明 |
|---|---|---|
| (无) | 32位 | 字(word)传输 |
| B | 8位 | 字节(byte)传输 |
| H | 16位 | 半字(halfword)传输 |
| SB | 8位 | 有符号字节加载(仅LDR) |
| SH | 16位 | 有符号半字加载(仅LDR) |
| D | 64位 | 双字(doubleword)传输 |
有符号加载指令(SB/SH)在加载时会进行符号扩展,将8/16位数据扩展到32位寄存器。例如加载一个-1的字节(0xFF):
- LDRB会得到0x000000FF
- LDRSB会得到0xFFFFFFFF
1.3 对齐要求与ARMv7扩展
内存对齐是影响访问效率和安全的重要因素。ARM架构传统上要求:
- 字(32位)访问必须4字节对齐
- 半字(16位)访问必须2字节对齐
在ARMv6及更早版本中,非对齐访问会导致:
- 如果启用对齐检查(cp15配置),触发对齐异常
- 否则执行修正操作:
- STR:地址向下取整到对齐边界
- LDR:地址取整后加载,然后进行数据旋转
ARMv7引入的非对齐访问支持极大
