对齐访问导致上的ARM Cortex-M4的错误 [英] Unaligned access causes error on ARM Cortex-M4

查看:1881
本文介绍了对齐访问导致上的ARM Cortex-M4的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有具有不是4字节对齐地址的对象。这导致在CPU一个HardFault错误时,有一个STR指令节省2寄存器。

I have an object that has an address that is not 4-byte aligned. This causes a HardFault error in the cpu when there is a STR instruction saving 2 registers.

这是生成的code:

   00000000 <_ZN8BaseAreaC1EPcmm>:
   0:   b510            push    {r4, lr}
   2:   4604            mov     r4, r0
   4:   6042            str     r2, [r0, #4]
   6:   e9c4 3102       strd    r3, r1, [r4, #8]
   a:   2001            movs    r0, #1
   c:   7420            strb    r0, [r4, #16]
   e:   b921            cbnz    r1, 1a <_ZN8BaseAreaC1EPcmm+0x1a>

这些寄存器当行4:6042 ......

These are the registers when at line "4: 6042..."

R0   08738B82  R8          0  
R1   08738BAE  R9          0  
R2          0  R10  082723E0  
R3       2FCC  R11         0  
R4   08738B82  R12         0  
R5   20007630  R13  2000CB38  

由于看到了STR指令的目标寄存器的4字节不对齐。指令 STR R2,[R0,#4]执行罚款。但HardFaults上的下一个 STRD R3,R1,[R4,#8] 。如果我手动更改寄存器R4为 08738B80 不hardfault。

As seen the target register for STR-instructions are not aligned on 4-byte. The instruction STR r2, [r0, #4] is executed fine. But it HardFaults on the next STRD r3, r1, [r4, #8]. If I manually change register R4 to 08738B80 it does not hardfault.

这是C ++ code产生上述ASM:

This is the C++ code that generates the above asm:

BaseArea::BaseArea(char * const pAddress, unsigned long startOffset, unsigned long endOffset) : 
m_pAddress(pAddress), m_start(startOffset), m_end(endOffset), m_eAreaType(BASE_AREA) {

M_START 是班上第一个变量,并且有相同的地址这(08738B82),m_end之后是继 0x08738B86

And m_start is the first variable in the class and has the same address as this (08738B82), m_end follows after on 0x08738B86.

我要如何在对象上4字节对齐?
任何人有一些其他的解决这个?

How do I get the object aligned on 4-byte? Anyone have some other solution to this?

推荐答案

在基于ARM的系统不能满足未对齐到4字节边界的32位字(因为你的错误是告诉你)。在x86上,你可以访问非对齐的数据,但是有对性能有巨大的打击。

On ARM-based systems you cannot address a 32-bit word that is not aligned to a 4-byte boundary (as your error is telling you). On x86 you can access non-aligned data, however there is a huge hit on performance.

ARM的边界错误(这里 )的例子,TLDR:存储指针到 unsigned char型,然后试图将其转换为双* (双指针)。

Example of boundary error on ARM (here), TLDR: storing a pointer to an unsigned char and then attempting to convert it to a double * (double pointer).

要解决你的问题,你就需要请求的内存块是4字节对齐,并复制不结盟字节+垃圾字节填充它,以确保它是4字节对齐(因此进行数据结构调整手动)。然后,您可以跨preT,作为4个字节的新地址一致反对。

To solve your problem, you would need to request a block of memory that is 4-byte aligned and copy the non-aligned bytes + fill it with garbage bytes to ensure it is 4 byte-aligned (hence perform data structure alignment manually). Then, you can interpret that object as 4-byte aligned from its new address.

从TurboJ在评论中,明确的错误:

From TurboJ in comments, the explicit error:

的Cortex-M3和M4默认允许对齐访问。但他们不允许与STRD指令unalinged访问,因此故障。

Cortex-M3 and M4 allow unaligned access by default. But they do not allow unalinged access with the STRD instruction, hence the fault.

您也可能会发现寻找到对ARM迫使数据结构调整有帮助

You may also find it helpful to look into this for forcing data structure alignment on ARM.

这篇关于对齐访问导致上的ARM Cortex-M4的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆