ARM LINUX 非对齐 编译,ARM非对齐操作异常解决过程

在测试MF固件时,发生一个非常诡异的异常,代码如下:

CLR_DBG_Commands::Monitor_EraseMemory* cmd = (CLR_DBG_Commands::Monitor_EraseMemory*)msg->m_payload;

debug_printf("EraseMemory addr=0x%08x len=%d\r\n", cmd->m_address, cmd->m_length);

指定第二行代码时,会跳到异常处理程序,发生了6号异常(用法异常Usage Fault)

我对ARM还是非常陌生,不知道怎么可能发生这个问题。

在今天之前,这行代码执行了无数次也未曾出错,最近也没有修改该函数或者相关函数的代码,昨天倒是大量修改了其它代码。

1,百度找资料

关键点是用法异常Usage Fault,以此为关键字搜索。有资料(http://www.docin.com/p-633872264.html)指出,用法异常包括:执行未定义指令、非对齐操作、除零。

前后两个显然不可能,中间这个非对齐操作倒是引起了我的注意。因为阅读MFPK代码的时候看到很多对齐操作的设计。

2,Keil调试

在Keil中调试这两行代码

0x080071DA 6A74 LDR r4,[r6,#0x24]1350: debug_printf("EraseMemory addr=0x%08x len=%d\r\n", cmd->m_address, cmd->m_length);

1351:

0x080071DC A012 ADR r0,{pc}+4 ;@0x08007228

0x080071DE E9D41200 LDRD r1,r2,[r4,#0]

0x080071E2 F001FD93 BL.W debug_printf (0x08008D0C)

抛出异常的是0x080071DE这一行,代码是LDRD r1,r2,[r4,#0],大意是把r4开始,偏移#0的数据加载到r1,下一个字加载到r2

从寄存其中看到,r4此时是0x200006D2,这是半字对齐而不是字对齐。

奇怪了,MDK为啥编译一个半字对齐的呢?

回到第一行代码的msg->m_payload,它是关键。因为它就是0x200006D2,如果r4没有字对齐,那么肯定跟这个msg->m_payload有关。

我们看看msg->m_payload是哪里分配的!

3,寻根

从代码中看到msg->m_payload来自msg->m_payload = pThis->m_receptionBuffer;

而m_receptionBuffer的声明

COM_HANDLE m_port;

UINT8 m_receptionBuffer[2048];

UINT32 m_flags;

UINT32 m_lastPacketSequence;

WP_Controller m_controller;

到这里,就明白了!

因为我昨天把typedef INT32 COM_HANDLE;改为了typedef INT16 COM_HANDLE;

非对齐操作相关资料

http://www.docin.com/p-218037008.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值