Assembly 什么决定了内存重新映射操作后的位置独立性?

Assembly 什么决定了内存重新映射操作后的位置独立性?,assembly,arm,gnu,remap,position-independent-code,Assembly,Arm,Gnu,Remap,Position Independent Code,我开始读米罗·萨梅克的书,发现自己被困在某一点上。引起我困惑的是PDF第10页的一个注释: 注意:函数low_level_init()可以在C/C++中编码,但有以下限制。该函数必须在ARM状态下执行,并且不能依赖.data节的初始化或.bss节的清除。此外,如果执行了内存重新映射,则它必须发生在低级别的函数_init()中,因为在该函数返回后,代码不再是位置独立的 代码“不再独立于位置”的确切含义是什么?从\u cstartup标签返回后,参考代码(可在PDF第7-9页查看)似乎仍然是位置独立

我开始读米罗·萨梅克的书,发现自己被困在某一点上。引起我困惑的是PDF第10页的一个注释:

注意:函数low_level_init()可以在C/C++中编码,但有以下限制。该函数必须在ARM状态下执行,并且不能依赖.data节的初始化或.bss节的清除。此外,如果执行了内存重新映射,则它必须发生在低级别的函数_init()中,因为在该函数返回后,代码不再是位置独立的

代码“不再独立于位置”的确切含义是什么?从
\u cstartup
标签返回后,参考代码(可在PDF第7-9页查看)似乎仍然是位置独立的。
\u cstartup
标签后面的说明唯一不同之处在于它们引用了链接器脚本中定义的标签(本指南第3节)


那么,重新映射究竟如何影响它后面的指令是否与位置无关呢?

位置无关是一个加载时间概念,而不是运行时概念。位置独立性是一种代码质量,允许它在内存中的任何地址加载,并且仍然可以工作,但位置独立性不是运行程序的质量

一旦我们有了引用代码的调用堆栈和/或(重新定位)数据,我们就不再有代码或数据的位置独立性,也不能移动它们。实际上,当程序开始执行时,位置独立性消失(尽管代码与位置无关)

通过调用(例如,
BL
)动态生成的返回地址以及指向代码的数据指针(代码指针向量(如vtables)和初始化的全局函数指针)都会破坏正在运行的程序的位置独立性

作者的警戒点是一种描述立场独立性消失的方式。更让人困惑的是,通过非常仔细的操作,它们允许实际移动代码,即使代码已经开始执行,所以在这里,位置独立性实际上会在执行开始后持续一小段时间

但是,如果不放弃位置独立性,程序就无法正常运行(例如调用和使用函数指针),因此他们选择在
低级别初始化
的末尾划清界限

例如,
reset
代码非常长,使用非标准调用调用
low_level_init
——为其提供
lr
值,而不使用
BL
mov-lr,pc
(这将捕获
cstartup
的预映射(ROM)地址)提供的
lr
值是(重新定位)
cstartup
的地址,
low\u level\u init
将“返回”到该地址


B
加上
MOV-lr,r1
就是调用。

你问作者时说了什么?@old_timer对不起,恐怕我不明白。我从来没有问过作者。当你问一个问题时,你会从这个问题开始,我们怎么知道作者想说什么。那么,如果答案没有意义,那么有了比你这里更多的信息,你就可以提出问题了。@old_timer很好。我将与作者联系并直接询问他们。如果我得到问题的答案,我一定会更新这篇文章。我明白了。因此,本说明的目的是强调位置无关代码在执行过程中固有的不适用性。非常感谢您的解释!不过,具体来说,当你说“位置独立性实际上在执行开始后持续了一小段时间”时,你指的是在
low_level_init
中设置主向量表和次向量表,对吗?是的,这样设置的代码小心地避免了重新定位的危险,但这是不可持续的,一旦捕捉到指向代码的指针,那么只会持续很短的时间——当然,只要他们想以极端的限制编码,因为他们可以控制。从技术上看,重新映射后不会重新定位
\u cstartup
。根据的第18.3.3节,此特定MCU的重新映射操作“导致通过内部存储器区域0(ROM地址空间)访问内部SRAM”。因此,启动代码似乎根本没有在内存中被“移动”,唯一被“移动”的是向量表。
    (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: