c++ - Unaligned access causes error on ARM Cortex-M4 -
i have object has address not 4-byte aligned. causes hardfault error in cpu when there str instruction saving 2 registers.
this 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 registers when @ 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 target register str-instructions not aligned on 4-byte. instruction str r2, [r0, #4]
executed fine. hardfaults on next strd r3, r1, [r4, #8]
. if manually change register r4 08738b80
not hardfault.
this c++ code generates 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
first variable in class , has same address this (08738b82)
, m_end follows after on 0x08738b86
.
how object aligned on 4-byte? have other solution this?
on arm-based systems cannot address 32-bit word not aligned 4-byte boundary (as error telling you). on x86 can access non-aligned data, there huge hit on performance.
example of boundary error on arm (here), tldr: storing pointer unsigned char
, attempting convert double *
(double pointer).
to solve problem, need request block of memory 4-byte aligned , copy non-aligned bytes + fill garbage bytes ensure 4 byte-aligned (hence perform data structure alignment manually). then, can interpret object 4-byte aligned new address.
from turboj in comments, explicit error:
cortex-m3 , m4 allow unaligned access default. not allow unalinged access strd instruction, hence fault.
you may find helpful this forcing data structure alignment on arm.
Comments
Post a Comment