Почему мы вычитаем 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 ответа:
Я нашел аналогичные коды запуска, как ваш в сети, которые имеют свой код хорошо прокомментированы. В этом стартовом коде , вы можете видеть на
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 слово стекового пространства для собственного использования, вне фрагмента, который вы показываете?