我纯粹是出于爱好原因,试图理解 PC 中的一些低级代码。我为随机的旧千兆字节 MB 下载了一个过时的 BIOS ROM 映像(https://www.gigabyte.com/Motherboard/GA-8I845GE775-G-rev-10/support#support-dl-bios https://www.gigabyte.com/Motherboard/GA-8I845GE775-G-rev-10/support#support-dl-bios),它已经快 15 年了,所以我希望它不会损害任何人的知识产权。我将使用该文件作为参考。
我一开始就被绊倒了。这些似乎是处理器上电后看到的第一条指令:
f000:fff0 ljmp 0xf000:0xe05b
f000:e05b jmp 0xf46c
f000:f46c cli
f000:f46d cld
f000:f470 smsw ax ; read CR0
f000:f473 test al, 1 ; test Protected Mode Enable
f000:f475 je 0xf480
[assuming PE is zero – jump:]
f000:f480 jmp 0xe043
f000:e043 mov al, 0x8f
f000:e045 out 0x70, al ; CMOS controller: disable NMI, set index 0xf
f000:e047 out 0xeb, al ; this port is presumably unoccupied: just a delay mechanism
f000:e049 in al, 0x71 ; read 0xf (CMOS Shutdown Status)
f000:e04b out 0xeb, al ; more delay
f000:e04d or al, al
f000:e04f jmp 0xf483
f000:f483 jne 0xf488
[assuming status = 0 (Power on or soft reset) – pass:]
f000:f485 call 0x4dee
假设计算机开机时 CMOS 关闭状态为零,则 BIOS 会发出一个调用f000:f485
。在早期,我们不会尝试检测是否存在任何 RAM。堆栈段和堆栈指针也尚未设置。代码位于f000:f485
确实看起来像一个函数并以一个结尾ret
。这怎么可能,在哪里call
存储返回地址?
或者我误解了从端口返回的值0x71
?我参考了这两个文档:
写作的意义0x8f
to 0x70
: https://wiki.osdev.org/CMOS#CMOS_Registers https://wiki.osdev.org/CMOS#CMOS_Registers
随后读取的值的含义0x71
: http://www.bioscentral.com/misc/cmosmap.htm http://www.bioscentral.com/misc/cmosmap.htm