为什么 BIOS 需要将(看似)随机地址中的值与第二条指令中的零进行比较?

Why BIOS need to compare a value in (seemly) randomized address to zero in the second instruction?

我正在尝试通过深入了解操作系统的底层细节来学习操作系统。我现在上的课程是 MIT 6.828 Operating System Engineering。实验室要求学生追踪 BIOS 以获取一些说明。 BIOS的前三条汇编指令如下:

0xffff0:    ljmp    [=10=]xf000,[=10=]xe05b
0xfe05b:    cmpl    [=10=]x0,%cs:0x6c48
0xfe062:    jne     0xfd2e1

我想不通的是第二个:cmpl [=11=]x0,%cs:0x6c48。它有什么作用?为什么在 jmp 到特定位置之前需要这个条件?我在网上搜索了一段时间,但仍然找不到解释。更棘手的是,我发现不同的人得到不同的地址来比较,比如这里的 0x6ac80x65a40x6c48

比较的具体内容取决于 BIOS 制造商,但显然 POST (Power on Self Test) processing. Some BIOSes may have completely different code that doesn't look anything like those instructions. Since you are using QEMU, the default BIOS being used is SeaBIOS. That cmpl is to determine if a reboot or a resume 的一些标志正在完成:

As noted above, on emulators SeaBIOS handles the 0xFFFF0000:FFF0 machine startup execution vector. This vector is also called on machine faults and on some machine "resume" events. It can also be called (as 0xF0000:FFF0) by software as a request to reboot the machine (on emulators, coreboot, and CSM).

The SeaBIOS "resume and reboot" code handles these calls and attempts to determine the desired action of the caller. Code flow starts in 16bit mode in romlayout.S:reset_vector() which calls romlayout.S:entry_post() which calls romlayout.S:entry_resume() which calls resume.c:handle_resume(). Depending on the request the handle_resume() code may transition to 32bit mode.

您可以查看 SeaBIOS 的 source code 以获得 entry_post 代码,这是 jmp [=13=]xf000,[=13=]xe05b 带您的地方:.

        ORG 0xe05b
entry_post:
        cmpl [=10=], %cs:HaveRunPost                // Check for resume/reboot
        jnz entry_resume
        ENTRY_INTO32 _cfunc32flat_handle_post   // Normal entry point

如果%cs:HaveRunPost处的32位值不为零则为resume操作,否则为reboot操作。 HaveRunPost 的地址或任何内部 BIOS 变量在 SeaBIOS 的一个版本与另一个版本之间可能不同。这可能是因为版本之间的代码更改; compiler/compiler 用于构建 ROM 的选项;选择的 BIOS 功能等