Адрес обработчика прерывания в векторе прерывания +1 от фактического адреса

Я перекрестно скомпилировал программу для cortex-m3. В стартовом коде все прерывания задаются в g_pfnVectors. Когда я дизассемблирую, по адресу 0x0 я вижу "значение указателя стека". Затем по адресу 0x4 дается адрес обработчика прерывания сброса. Это продолжается со следующими адресами системных прерываний.

Вот мой вопрос: почему в векторе прерывания адреса обработчиков прерываний +1 от фактического адреса. Адрес обработчика ResetISR 0x184, но в таблице прерываний 0x185. Это относится ко всем другим адресам обработчиков прерываний. В чем причина этого?

    00000000 <g_pfnVectors>:
       0:   10008000    andne   r8, r0, r0
       4:   00000185    andeq   r0, r0, r5, lsl #3
       8:   00000215    andeq   r0, r0, r5, lsl r2
       c:   0000021d    andeq   r0, r0, sp, lsl r2

    00000184 <ResetISR>:
     184:   b580        push    {r7, lr}
     186:   b084        sub sp, #16
     188:   af00        add r7, sp, #0
     .......

    00000214 <NMI_Handler>:
     214:   b480        push    {r7}
     216:   af00        add r7, sp, #0
     218:   e7fe        b.n 218 <NMI_Handler+0x4>
     21a:   bf00        nop
     .......
    0000021c <HardFault_Handler>:
     21c:   b480        push    {r7}
     21e:   af00        add r7, sp, #0
     220:   e7fe        b.n 220 <HardFault_Handler+0x4>
     .......

person zenprogrammer    schedule 21.02.2015    source источник


Ответы (1)


Я нашел ответ в Справочном руководстве по архитектуре ARMv7-M, раздел Определение векторной таблицы (B1.5.3):

Таблица Vector должна быть естественным образом выровнена по степени двойки, значение выравнивания которой больше или равно (Число поддерживаемых исключений x 4) с минимальным выравниванием 128 байт. При включении или сбросе процессор использует запись со смещением 0 в качестве начального значения для SP_main, см. Регистры SP на стр. B1-572. Все остальные записи должны иметь бит[0] равным 1, поскольку этот бит определяет бит EPSR.T в записи об исключении. Дополнительные сведения см. в разделах «Поведение при сбросе» на стр. B1-586 и «Поведение при входе в исключение» на стр. B1-587. При вводе исключения, если бит [0] связанной записи таблицы векторов установлен в 0, выполнение первой инструкции вызывает INVSTATE UsageFault, см. Регистры состояния специальной программы, xPSR на стр. B1-572 и Поведение при сбое на стр. Б1-608. Если это происходит при перезагрузке, это переходит в состояние HardFault, поскольку UsageFault отключается при перезагрузке. Дополнительную информацию см. в разделе Повышение приоритета на странице B1-585.

person zenprogrammer    schedule 21.02.2015
comment
Короче говоря, бит 0 определяет, что инструкция находится в режиме большого пальца. Насколько мне известно. - person Pait; 27.04.2015