一个alignment trap的解决办法

在移植一份代码时,遇到一个alignment trap的错误:

 经过定位,触发alignment trap的汇编语句如下:

printk("status %#x\r\n", stData.info->status);

38c0:    f8d4 3181     ldr.w    r3, [r4, #385]    ; 0x181
38c4:    f240 2261     movw    r2, #609    ; 0x261
38c8:    485d          ldr    r0, [pc, #372]
38ca:    9301          str    r3, [sp, #4]
38cc:    4b57          ldr    r3, [pc, #348]
38ce:    9200          str    r2, [sp, #0]
38d0:    4619          mov    r1, r3
38d2:    f7ff fffe     bl    0 <printk>

原因是ARM对ldr指令访问内存时要求4字节对齐,根据r4+0x181=0xd0b02181,这个地址不是4字节对齐的,所以arm触发了alignment异常。

造成这个对齐异常,与下面这个结构体的定义有关:

#pragma pack(push, 1)

struct
{
    unsigned int bit_0_3     :4;  
    unsigned int bit_7_4     :4;
    unsigned int status      :32; 
    ......
};

#pragma pack(pop)

由于使用了1字节对齐(为了节省内存),所以访问status成员时,就访问了4字节对齐偏移1字节的地址了。 

解决办法

使用-mno-unaligned-access编译选项,该编译选项是 ARM 架构编译器的优化选项,用于禁止编译器生成可能导致非对齐内存访问的指令。

重新编译后对应的汇编代码:

printk("int_status %#x\r\n", stData.info->status);
3b50:    f894 2182     ldrb.w    r2, [r4, #386]    ; 0x182
3b54:    f894 3181     ldrb.w    r3, [r4, #385]    ; 0x181
3b58:    4879          ldr    r0, [pc, #484]    ; (3d40 <EncFwAnaNodeInfo+0x1618>)
3b5a:    ea43 2302     orr.w    r3, r3, r2, lsl #8
3b5e:    f894 2183     ldrb.w    r2, [r4, #387]    ; 0x183
3b62:    ea43 4302     orr.w    r3, r3, r2, lsl #16
3b66:    f894 2184     ldrb.w    r2, [r4, #388]    ; 0x184
3b6a:    ea43 6302     orr.w    r3, r3, r2, lsl #24
3b6e:    f240 2261     movw    r2, #609    ; 0x261
3b72:    9301          str    r3, [sp, #4]
3b74:    4b6d          ldr    r3, [pc, #436]    ; (3d2c <EncFwAnaNodeInfo+0x1604>)
3b76:    9200          str    r2, [sp, #0]
3b78:    4619          mov    r1, r3
3b7a:    f7ff fffe     bl    0 <printk>

发现之前的

ldr.w    r3, [r4, #385] 

变成了

ldrb.w    r2, [r4, #386] 

ldrb.w    r3, [r4, #385]

ldrb.w    r2, [r4, #387] 

ldrb.w    r2, [r4, #388]

这是一种以时间换空间的解决方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值