1. ARM架构下的非对齐访问问题解析
在嵌入式开发中,内存对齐是一个经常被忽视却又至关重要的问题。最近我在使用Keil MDK-ARM开发环境调试一段简单的内存操作代码时,遇到了一个令人困惑的现象:明明是小端序的ARM处理器,为何对非对齐地址的32位整型写入会得到完全不符合预期的结果?这个看似简单的现象背后,其实隐藏着ARM架构设计的重要特性。
1.1 问题现象还原
让我们先复现这个典型的问题场景。考虑以下测试代码:
#pragma pack(1)
unsigned char buf[40];
int main(void) {
*((short *)&buf[0]) = 0x77ff; // 写入16位数据
*((int *)&buf[2]) = 0x12345678; // 在非4字节对齐地址写入32位数据
printf("%x %x %x %x \n", buf[0], buf[1], buf[2], buf[3]);
}
按照小端序的预期,内存布局应该是:
- buf[0]: FF (short的低字节)
- buf[1]: 77 (short的高字节)
- buf[2]: 34 (int的第三字节)
- buf[3]: 12 (int的最高字节)
但实际输出却是: 78 56 34 12 。这个结果看起来像是整个32位数值被"旋转"了——最高字节78出现在了最低地址,完全打乱了我们的预期。
1.2 问题本质剖析
这种现象的根本原因在于ARM架构对非对齐访问(unaligned access)的特殊处理。与x86架构不同,传统ARM处理器(ARM7/ARM9)的硬件设计不允许对16位或32位数据进行非对齐访问。这里的"对齐"指的是:
- 16位数据(short)必须存储在2字节对齐的地址(地址%2=


4541


被折叠的 条评论
为什么被折叠?



