Позиция не зависит от времени загрузки, а не от времени выполнения. Независимость от позиции - это качество кода, которое позволяет загружать его по любому адресу в памяти и будет по-прежнему работать, но независимость от позиции не является качеством работающей программы.
Как только мы получим стек вызовов и / или (перемещенные) данные, относящиеся к коду, мы больше не обладаем позиционной независимостью ни от кода, ни от данных и не можем их перемещать. Фактически независимость позиции исчезает, когда программа начинает выполнение (несмотря на код, независимый от позиции).
Оба адреса возврата - динамически генерируемые при вызове (например, BL
) - а также указатели данных на код (векторы указателя кода ( как в vtables) и инициализированные указатели глобальных функций) уничтожают независимость позиции для работающей программы.
Предупреждающий узел автора - это способ описания исчезновения независимости позиции. Добавление к путанице заключается в том, что благодаря очень осторожной работе они позволяют фактически перемещать код, даже если его выполнение уже началось, поэтому здесь у нас есть независимость позиции, фактически продолжающаяся некоторое небольшое количество после начала выполнения.
Но Программа не может нормально функционировать (например, совершать вызовы и использовать указатели функций), не отказываясь от независимости позиции, и поэтому они решают нарисовать линию на песке в конце low_level_init
.
Например, reset
код очень длинен, чтобы использовать нестандартный вызов для вызова low_level_init
- предоставляя ему значение lr
без использования либо BL
, либо mov lr,pc
(который будет захватывать предварительно преобразованный (ROM) адрес из cstartup
.) Предоставленное значение lr
является адресом (1022 *), на который low_level_init
«вернется»!
(10) LDR r0,=_reset /* pass the reset address as the 1st argument */
(11) LDR r1,=_cstartup /* pass the return address as the 2nd argument */
(12) MOV lr,r1 /* set the return address after the remap */
(13) LDR sp,=__stack_end__ /* set the temporary stack pointer */
(14) B low_level_init /* relative branch enables remap */
_cstartup:
Это B
в сочетании с MOV lr,r1
это вызов.