gpt4 book ai didi

assembly - 什么决定了内存重映射操作后的位置无关性?

转载 作者:行者123 更新时间:2023-12-02 02:56:47 25 4
gpt4 key购买 nike

我已经开始阅读 Miro Samek 的 "Building Bare-Metal ARM Systems with GNU"并发现自己陷入了某个点。导致我困惑的原因可以在 PDF 第 10 页的注释之一中找到:

NOTE: The function low_level_init() can be coded in C/C++ with the following restrictions. The function must execute in the ARM state and it must not rely on the initialization of .data section or clearing of the .bss section. Also, if the memory remapping is performed at all, it must occur inside the low_level_init() function because the code is no longer position-independent after this function returns

代码到底如何“不再与位置无关”?从 low_level_init 返回后/在 _cstartup 标签之后,引用的代码(可在 PDF 的第 7 - 9 页上查看)似乎仍然与位置无关。 _cstartup 标签后面的指令似乎唯一不同的是它们引用了链接描述文件中定义的标签(指南的第 3 节)。

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

最佳答案

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

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

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

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

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

例如,reset代码花费了很长的篇幅来使用非标准调用来调用 low_level_init — 为其提供 lr值而不使用 BLmov lr,pc (这将捕获 cstartup 的预重映射 (ROM) 地址。) lr提供的值是(重定位)cstartup的地址到其中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:

那个BMOV lr,r1 结合是调用。

关于assembly - 什么决定了内存重映射操作后的位置无关性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60937370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com