为什么 /arch/x86/boot/header.S 在汇编中?

Bat*_*Bat 0 c assembly operating-system linux-kernel

为什么这个文件是用汇编语言编写的,而它可以简单地使用更简单的语言(如 c)?为什么没有人仍然尝试用 c 重写它?

小智 5

它是与引导相关的代码并且依赖于体系结构。一些引导加载程序代码结构(例如,与堆栈相关的)可能无法在 C 中表示,除非违反其主要约定。同时,在引导过程中通常不可避免地使用此类构造。

嗯,有一种思想认为您可以用C 语言编写与启动相关的代码,但无论如何您仍然需要在其中使用大量内联汇编来访问代码中非常低级的功能。

此外,典型的引导加载程序必须应对一些限制。限制之一(至少是这样x86)是当机器加电时,处理器开始以 16 位实模式运行。可供使用的 RAM 不足 1 MB(引导设施需要足够小才能容纳),没有可用的虚拟内存机制,并且一般来说,内存寻址模式受到很大限制。当 BIOS POST 程序从任一引导设备(例如 HDD)读取引导扇区时,加载的程序必须从磁盘读取更多设施到内存并将控制权传递给它们。显然,由于此时没有操作系统正在运行,因此没有可用的操作系统设备驱动程序,并且没有适用的标准 C 方法(例如,使用标准 IO 库)。相反,BIOS 提供了设备驱动程序,这些驱动程序提供一组明确定义的中断(例如https://en.wikipedia.org/wiki/INT_13H)来访问不同引导驱动器上的数据。因此,粗略地说,启动管理器必须用汇编语言编写,才能在实模式下使用一组非常特定的 BIOS 功能。

总而言之,考虑到所有要点(代码大小、16 位实模式限制、需要使用 BIOS 特定功能以及无法用 C 表示的代码结构),答案是用汇编语言编写整个代码将是最有效和明确的方式,而不是扩展 C 来处理非标准构造或使用可读性差的 C 和内联汇编代码的混合。

PS 如果您对引导加载程序内部结构的更详细描述感兴趣,参考 FreeBSD 引导和内核初始化的一个非常雄辩的示例会很有用:https://www.freebsd.org/doc/en_US.ISO8859-1 /books/arch-handbook/boot-overview.html