嵌入式技术论坛
直播中

ss

6年用户 8762经验值
擅长:电源/新能源 制造/封装 RF/无线
私信 关注
[经验]

如何对ARM架构下的非对齐访问编译进行测试

关于 ARM 架构下的非对齐访问编译选项说明
-munaligned-access
-mno-unaligned-access

Enables (or disables) reading and writing of 16- and 32- bit values from addresses that are not 16- or 32- bit aligned.
By default unaligned access is238 Using the GNU Compiler Collection (GCC) disabled for all pre-ARMv6,
all ARMv6-M and for ARMv8-M Baseline architectures, and enabled for all other architectures.
If unaligned access is not enabled then words in packed data structures are accessed a byte at a time.
The ARM attribute Tag_CPU_unaligned_access is set in the generated object file to either true or false,
depending upon the setting of this option.
If unaligned access is enabled then the preprocessor symbol __ARM_FEATURE_UNALIGNED is also defned.

系统中的结构体数据,如果添加了 __packed 属性,则会以紧凑的方式进行内存排布,此时其中的一些数据在内存中的排布就是非对齐的。在程序运行时,如果系统不允许非对齐访问,此时对该结构体中的非对齐数据进行访问,则会出现 data abort 的错误。
如果在编译和链接时添加 -mno-unaligned-access 不支持非对齐内存访问选项,将会告诉编译器,生成操作这些非对齐数据指令,需要一个字节一个字节地读取,然后将结果拼凑成最终的数据。用这种方式操作数据降低了数据的访问效率,但是可以避免出现非对齐访问错误。
在 armv7 中可以开启或者关闭非对齐访问检查,例如使用如下指令关闭非对齐访问检查:
    /* disable the data alignment check */
    mrc p15, 0, r1, c1, c0, 0
    bic r1, #(1<<1)
    mcr p15, 0, r1, c1, c0, 0
如果关闭了非对齐访问检查,此时 CPU 访问非对齐数据将不会报错,在底层硬件实现时,可能会将一次访问拆成多次对齐访问来实现,但是在软件层是不感知的。尽管如此,还是降低了数据的访问效率。另外,一些强序内存(例如设备内存)是不支持非对齐访问的。
非对齐访问参数测试
编译如下源码:
struct st_a {
    char a;
    int  b;
} __attribute__((packed));
int get_b(struct st_a *p)
{
    return p->b;
}
编译命令如下:

支持非对齐访问

arm-none-eabi-gcc.exe -S arm.c -o arm_with_unaligned_access.s -O2 -mcpu=cortex-a7

不支持非对齐访问

arm-none-eabi-gcc.exe -S arm.c -o arm_no_unaligned_access.s -O2 -mno-unaligned-access -mcpu=cortex-a7

实验结果如下:


可以清楚地在汇编在代码中看到,如果开启了禁止非对齐访问,在操作非对齐地址的数据时,读取了多次,每次只读取一个字节。

更多回帖

发帖
×
20
完善资料,
赚取积分