我正在研究一些汇编代码,但我不明白为什么通常将 SP 指向程序入口点或其他随机位置。例如这个树莓派的裸机代码,指向0x80000000,但是.text被映射到0x8000,有什么原因吗?
更好的问题是为什么 Linux 内核加载器在零以外的地方加载内核。
根据不同时代的linux内核习惯(对于arm嵌入式系统)(或特定端口),一些非零地址如0x8000、0x80000等可能是linux内核的入口点。例如,这为 DTB 留下了空间。但是,如果编写裸机,那么这些都不重要,您只需拥有 0x8000 或更多字节的内存就在那里,其中可能有 32 个字节左右是您的异常表。
因此,将裸机默认入口点所在的系统的堆栈指针设置为 0x8000(无需对系统进行额外更改以更改入口点(例如更改为 0x00000000))。这为您提供了几乎 0x8000 字节的堆栈以及正确的入口点(对于系统)。
这也允许公开示例,这些示例可能只适用于您不必说尝试确定内存总量的情况,即使您知道板上有多少内存,仍然有一个可以修改的控件来更改GPU 和 ARM 之间的比率。
一般来说,您需要为堆栈指针设置一个位置,您可以使链接器脚本变得过于复杂,并尝试控制它的位置并固定其大小(从链接器的角度来看,不是现实)。或者,每次下一个系统出现更多内存时,您都可能会发生崩溃并重新调整代码。或者将其放在 0x10000 或某个适用于所有平台变体的地址处。并处理这个问题。
这是一个非常干净的解决方案,允许公开示例,代码在内核执行的位置加载,因此不需要额外的工作来解释这一点。堆栈指针从入口点向下工作,因为那里有大量迄今为止未使用的空间。