对齐访问导致上的ARM Cortex-M4的错误 [英] Unaligned access causes error on 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屋!