魔数 0x7c00

在涉及到计算机系统引导部分的内容时,经常会看到这个魔数(maigc number) 0x7c00

找到一篇文章讲述这个魔数的来龙去脉 Why BIOS loads MBR into 0x7C00 in x86 ,简单地小结下文中的内容:

  1. 0x7c00 这个魔数和 CPU 没有直接关系,并不属于 CPU 手册中的规定内容

  2. 它第一次出现在 IBM PC 5150 ROM BIOS INT 19h handler,就是 IBM PC 5150 基础输入输出系统中的第19个中断处理句柄中

  3. 之所以在 CPU 手册中没有任何关于 0x7c00 的细节,是因为它完全是属于 BIOS 的规格参数。

  4. 来自 IBM PC 5150 开发团队的解释是:

    1. 他们在设计系统时以内存最小为 32KiB 为目标
    2. 他们希望在 32KiB 之内流出更多的空间给 OS 来完成自身的引导
    3. 8086/8088 使用 0x0-0x3FF 来存放中断矢量,紧随其后的是 BIOS 的数据段
    4. 引导扇区(boot sector) 是 512字节,并且引导引导程序的栈大小为 512字节
    5. 所以 BIOS 将引导程序载入到 0x7c00 位置,引导程序将使用 32KiB 的最后 1024B 的内容

    在 OS 载入完成后,引导扇区在内存中占据的内容将不再被使用,因此 OS 和应用程序可是使用这块内存。在 OS 载入后,内存中的情形类似:

    +--------------------- 0x0
    | Interrupts vectors
    +--------------------- 0x400
    | BIOS data area
    +--------------------- 0x5??
    | OS load area
    +--------------------- 0x7C00
    | Boot sector
    +--------------------- 0x7E00
    | Boot data/stack
    +--------------------- 0x7FFF
    | (not used)
    +--------------------- (...)
    

    其实我感觉上面的 原因2 真的有些牵强。因为可以将 OS load area 和 boot sector/boot data 调换一个位置。将 OS load area 夹在中间的设计真的让人摸不着头脑。 BIOS 将控制权交给 boot loader 之后,boot loader 去哪里载入 OS 就不关 BIOS 的事情了。

所以概括性地来说,0x7c00 对于 BIOS 开发者来说是向后兼容的结果。而对于 boot loader 的开发者来说,由于 BIOS 会将引导程序载入到 0x7c00 的位置,因此相关的代码要根据这个因素进行调整,这也就是引导程序的汇编代码中都会在头部出现类似 ORG 0x7C00 的原因。