ARMClang非对齐8位访问优化为32位LDR致Cortex-A9数据中止问题
问题解答
编译器优化行为的原因
- Arm Compiler 6(armclang)在默认优化策略下,会基于C标准的未定义行为规则做优化:当代码从
unsigned char*转换为32位类型指针(如uint32_t*)并执行加载操作时,编译器默认假设该指针指向的地址是32位对齐的。因为C标准明确规定,不对齐的指针类型转换属于未定义行为,编译器有权忽略这种场景,生成更高效的对齐访问指令(比如单条LDR)。 - FatFS的
ld_dword函数逻辑上是通过字节拼接实现小端4字节数据加载,但编译器会将这种操作优化为直接的32位加载——它认为手动字节拼接的逻辑等价于对齐的32位读取,从而忽略了实际输入指针可能指向非对齐地址的情况。
Arria 10 HPS片内RAM的限制
Cortex-A9处理器本身支持非对齐内存访问(可通过CP15寄存器配置),但Arria 10 HPS的**片内RAM(OCM)**存在硬件层面的对齐限制:该区域不允许非对齐的32位访问,即使CPU开启了非对齐访问权限,硬件仍会触发数据中止异常,导致镜像重启。这是部分SoC片内RAM的设计特性,目的是简化硬件逻辑、提升访问效率。
关于-mno-unaligned-access的作用
添加该编译选项后,编译器会强制禁用所有非对齐的内存访问优化,针对ld_dword这类场景,会生成逐字节读取再拼接的指令序列,而非单条LDR,从而避开Arria 10 HPS片内RAM的对齐限制,解决数据中止问题。
内容的提问来源于stack exchange,提问作者Tom Carpenter
相关产品推荐
相关产品推荐

