为何-munaligned-access/-mno-unaligned-access未触发预期总线错误?
为什么ARMv7下
-mno-unaligned-access选项未触发未对齐访问错误? 问题描述
测试代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { unsigned char test[64]; memset(test,0, sizeof(test)); int loop = 0; for (loop = 0; loop < sizeof(test); loop++) { test[loop] = loop; } printf("%d,%d,%d,%d\n", *((int *)(test + 1)), *((int *)(test+2)), *((int *)(test+3)),*((int *)(test + 4))); return 0; }
使用允许未对齐访问的编译选项编译时:
-g -O0 -Wall -Werror -Waddress -Warray-bounds -Wdiv-by-zero -Wfloat-equal -Wno-unused-function -Wno-format-truncation -Wno-format -Wno-stringop-overflow -Wno-stringop-truncation -Wno-float-equal -Wno-sign-compare -fexpensive-optimizations -frename-registers -fno-omit-frame-pointer -ftree-vectorize -finline-functions -finline-limit=64 -fstack-protector-strong -funwind-tables -ffunction-sections -fPIE -pie -march=armv7-a -mfpu=neon -mfloat-abi=hard -munaligned-access
程序运行正常,未触发总线错误。
接着使用禁用未对齐访问的编译选项:
-g -O0 -Wall -Werror -Waddress -Warray-bounds -Wdiv-by-zero -Wfloat-equal -Wno-unused-function -Wno-format-truncation -Wno-format -Wno-stringop-overflow -Wno-stringop-truncation -Wno-float-equal -Wno-sign-compare -fexpensive-optimizations -frename-registers -fno-omit-frame-pointer -ftree-vectorize -finline-functions -finline-limit=64 -fstack-protector-strong -funwind-tables -ffunction-sections -fPIE -pie -march=armv7-a -mfpu=neon -mfloat-abi=hard -mno-unaligned-access
程序依然运行正常,未出现预期的总线错误。
疑问:为何-mno-unaligned-access选项未按预期生效?
原因分析
ARMv7硬件的实际行为
ARMv7-A架构的多数主流处理器(如Cortex-A系列)本身硬件支持未对齐访问,-mno-unaligned-access只是让编译器生成的代码假设硬件不允许未对齐访问,而非强制硬件禁用该功能。只有当代码中使用了要求对齐的指令(如多字节加载LDR)访问未对齐地址时,才会触发总线错误。-O0优化等级的代码生成策略
在-O0(无优化)模式下,GCC为了严格贴合源码逻辑,会避免生成可能引发异常的优化指令。对于*((int *)(test + 1))这种未对齐的int指针解引用,编译器会生成多个单字节加载指令(如LDRB),再将这些字节拼接成int值——这种方式根本不会用到需要地址对齐的多字节加载指令,自然不会触发总线错误。触发预期错误的验证方式
如果想看到-mno-unaligned-access的效果,可以尝试:
- 将优化等级提升到
-O1或更高,此时编译器会优先使用高效的多字节加载指令,访问未对齐地址时就会触发总线错误。 - 手动编写汇编代码,直接使用
LDR指令访问未对齐地址,此时在-mno-unaligned-access编译选项下会立即触发异常。
内容的提问来源于stack exchange,提问作者magic-tab-01
相关产品推荐
相关产品推荐

