2015-02-22 7 views
0

Мои ARM Envrionment являетсяПочему адрес инструкции ARM не выравнивается по моей среде ARM?

корень @ Линаро-разработчик: ~ # uname -a Linux Линаро-разработчик 3.2.0 # 7 SMP Чт 28 февраля 16:20:18 PST 2013 armv7l armv7l armv7l GNU/Linux

И моя сборка

.section .text 
.global _start 
_start: 
     .code 32 
     #Thumb-Mode on 
     add r6, pc, #1 
     bx r6 
     .code 16 
     sub r4, r4, r4 
     mov r0, r4 
     ldr r2, =0x80047dbc 
     blx r2 
     ldr r2, =0x80047a0c 
     blx r2 

Однако, когда я пытаюсь отладки с помощью GDB, ПК не собирается суб r4, r4, r4 GDB состояние

(gdb) x/3i $pc 
=> 0x83c8: add r6, pc, #1 
    0x83cc:  bx r6  ;r6 = 0x83d1 
    0x83d0: stcne 11, cr1, [r0], #-144 ; 0xffffff70 
(gdb) x/3i 0x83d1 
    0x83d1: subs r4, r4, r4 
    0x83d3: adds r0, r4, #0 
    0x83d5: ldr r2, [pc, #4] ; (0x83dc) 

сабвуфер r4, r4, r4 адрес 0x83d1 0x83d1 не выровнен

Почему мой код сборки находится на выровненный адрес?

+0

pc собирается 0x83d0, а затем 0x83d2 (Thumb) Однако я хочу выполнить 'subs r4, r4, r4'. Что мне делать? Когда я выполняю код сборки, произойдет «Сегментный сбой» –

+0

Каков адрес доступа, вызывающий ошибку? –

+0

(GDB) х/3i $ шт => 0x83c8: \t \t добавить r6, PC, # 1 0x83cc: \t \t BX r6 0x83d0: \t \t stcne 11, CR1, [г0], # -144 \t; 0xffffff70 (gdb) ni Не удается получить доступ к памяти по адресу 0x0 0x000083cc in ??() (gdb) si 0x000083d0 in ??() (gdb) x/3i $ pc => 0x83d0: \t stcne \t 11, cr1, [r0], # -144 \t; 0xffffff70 0x83d4: \t \t ldrmi r4, [R0, R1, LSL # 20] 0x83d8: \t \t ldrmi r4, [R0, R1, LSL # 20] (GDB) п 0x000083d2 в ??() (GDB) х/3i $ шт => 0x83d2: \t \t BMI 0x4f45a 0x83d6: \t \t BMI 0x5a21e 0x83da: \t \t ldcvc 7, cr4, [r12, # 576]! \t; 0x240 (gdb) c Постоянно. Запрограммированный сигнал SIGSEGV, ошибка сегментации. 0x80047dbc in ??() –

ответ

2

A (полный) ARM-процессор может выполнять инструкции в состоянии выполнения ARM или Thumb - грубо говоря, разница между универсальностью полного 32-битного слова инструкции или эффективностью кода более ограниченного 16- бит один.

При ветвлении на адрес, содержащийся в регистре, у вас есть возможность установить состояние ARM или Thumb с LSB содержимого регистра, что, по-видимому, является тем, что делает отладчик кода - разветвление на 0x83d1 будет установите Thumb state, но фактический адрес целевой команды будет 0x83d0, который будет выровнен по 16 бит.

Напротив, если разветвление на немедленное смещение, вы не можете установить режим с помощью LSB, но вместо этого можете выбрать между B/BL, который сохраняет состояние, или BX/BLX, который переключает его.

Обратите внимание, что некоторые меньшие ARM-сердечники, предназначенные для встроенного использования только поддерживают режим Thumb и не могут выполнять инструкции ARM.

+2

Обратите внимание, что компьютер всегда регистрируется содержит правильно выровненный адрес (и вы получите ошибку, если он этого не делает) - lsb __соответствующего_значения_ на ПК в интерфейсе взаимодействия Это важно. Фактическое состояние заканчивается бит T CPSR. Конечно, как gdb выбирает представлять вещи, может быть, другое дело. – Notlikethat

+0

Код находится по адресу 0x83d0, а не 0x83d1 (хотя ваш отладчик помогает отображать его по адресу, помеченному в соответствии с вашей строкой). Разве это не работает? Что произойдет, если вы его проследите? –

Смежные вопросы