У меня есть объект с адресом, не выровненным по 4 байтам. Это вызывает ошибку HardFault в процессоре, когда есть инструкция STR, сохраняющая 2 регистра.
Это сгенерированный код:
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..."
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
, это не приведет к жесткому сбою.
Это код C++, который генерирует приведенный выше 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
является первой переменной в классе и имеет тот же адрес, что и this (08738B82)
, m_end следует после 0x08738B86
.
Как мне выровнять объект по 4 байтам? У кого-нибудь есть другое решение для этого?
class
илиstruct
, которое вы здесь используете (значение вr0
, вероятно, равноthis
объекта, с которым мы имеем дело. Другими словами, какой исходный код использовался для его создания? - person Mats Petersson   schedule 16.08.2013BaseArea
, а также где вызывается конструктор? - person Mats Petersson   schedule 16.08.2013