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.
This is the generated 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>
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
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.
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) {
And m_start
is the first variable in the class and has the same address as this
(0x08738B82
), m_end
follows after on 0x08738B86
.
How do I get the object aligned on 4-byte?
Anyone have some other solution to this?
Best Answer
On ARM-based systems you frequently 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. Where an ARM part does support unaligned accesses (e.g. single word normal load), there is a performance penalty and there should be a configurable exception trap.
Example of boundary error on ARM (here), TLDR: storing a pointer to an
unsigned char
and then attempting to convert it to adouble *
(double pointer).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.
From TurboJ in comments, the explicit error:
You may also find it helpful to look into this for forcing data structure alignment on ARM.