Почему мы вычитаем 4 из arm926ejs reset перед загрузкой его в sp?


У меня есть стартовый код для ARM926ej-s, который поддерживает ISA ARMv5TEJ. Код запуска выглядит следующим образом, но я переключил некоторые команды/данные с комментариями для ясности. Строки, которые мне до сих пор непонятны, помечены комментарием "@???????????????????????????????????????????????????????".

Интересно, почему мы должны вычитать "#4 " из значения (расположение "arm926ejs_reset"), хранящегося в регистре " r3"? А затем загрузите его в указатель стека 4 строками позже, где мы устанавливаем стеки для первого режима процессора, который является быстрым прерыванием режим.

__start:
arm926ejs_reset:

@here there is image header data needed by ISROM

arm926ejs_reset_handler:

    @here we disable MMU, I-cache, D-cache, flush them... and prepare the mcpu.

    LDR   r5, =inVirtMem

    @here we enable MMU.

    MOV   pc, r5 

    NOP
    NOP
    NOP

inVirtMem:
    ADR   r3, arm926ejs_reset @load location of "arm926ejs_reset" label in r3
    MOV   r1, #IF_MASK

    SUB   r3, r3, #4 @???????????????????????????????????????????????????????

    ORR   r0, r1, #MODE_FIQ
    MSR   cpsr_cxsf, r0
    MOV   sp, r3 @???????????????????????????????????????????????????????????
    SUB   r3, r3, #FIQ_STACK_SIZE

...
2 2

2 ответа:

Я нашел аналогичные коды запуска, как ваш в сети, которые имеют свой код хорошо прокомментированы. В этом стартовом коде , вы можете видеть на Line 186, что r3 указывает на MMU базовый адрес. MMU опережает его базовый адрес. т. е. если MMU_BASE_ADDRESS=0x400, то записи MMU будут находиться в 0x400, 0x404 0x408 и т.д. Теперь в Line 217 r3 вычитается на 4 и затем присваивается SP на Line 222. Если мы не вычтем 4, то наша первая запись стека (заметим, что стек растет в обратном направлении от MMU макет) будет перезаписан на первой записи MMU! Отсюда и вычитание.

Аналогично в вашем примере, если мы не вычитаем 4, ваш стек будет перезаписан на самом обработчике сброса. Ваша программа пойдет на бросок.

Еще один пример-это начальный код, где они собираются закончить IRAM и вычесть 4. Конец IRAM подразумевает только снаружи IRAM и, следовательно, вычитание, чтобы войти внутрь IRAM

Обратите внимание, что стек является рост вверх в этом конкретном примере (или в сторону более низких адресов ).(Стеки ARM могут расти в любом направлении)

Моя догадка: стек должен быть расположен ниже для надписи (предположительно, запись на этикетку была бы плохой вещью), поэтому автор, хотя он должен был быть скорректирован вниз на одно слово.

Это действительно кажется странным - обычно стек используется в режимеполного декодирования , поэтому начальное значение указателя стека никогда не записывается. Если вы не можете доказать обратное, я не удивлюсь, если это был (безвредный) баг.

Это может быть резервированием a слово стекового пространства для собственного использования, вне фрагмента, который вы показываете?