2017-03-04 66 views
2

我是新装配。在试图找出BIOS的功能时,我使用gdb来追踪它。但是,我发现了一些非常奇怪的东西。
代码段是这样的:BIOS从不同端口读取两次到同一行中的同一寄存器

[f000:d129] 0xfd129: mov eax,0x8f 
[f000:d12f] 0xfd12f: out 0x70,al 
[f000:d131] 0xfd131: in  al,0x71 
[f000:d133] 0xfd133: in  al,0x92 
[f000:d135] 0xfd135: or  al,0x2 
[f000:d137] 0xfd137: out 0x92,al 

我不知道为什么在BIOS从连续端口0x71和0x92读取。第二条指令是否覆盖从端口0x71读取的值?那么为什么它从端口0x71读取?

谢谢!

回答

4

IO端口0x70是“CMOS/RTC索引寄存器”,IO端口0x71是“CMOS/RTC数据寄存器”。要访问CMOS中的某些内容,您应该设置索引,然后读/写数据寄存器。

对于某些RTC芯片,如果设置索引并且不读取或写入数据寄存器,则芯片处于未定义状态。这意味着如果你想为以后设置一个索引,你必须从数据寄存器中读取,以避免现在和之后的“未定义状态”。

换句话说;所读取的价值是不相关的 - 阅读会产生副作用,这是重要的副作用。

+0

端口0x70还用于禁用/启用NMI,如果位7为0,则启用NMI,如果位7为1,则禁用NMI。因此,代码禁用NMI,然后根据您给出的原因进行虚拟读取端口0x71。 –

+0

@RossRidge:花了我好几年才终于忘记了可怕的“忽略灾难性的硬件故障并继续勇敢地向前发展”的可能性。我现在好悲伤。 ;-) – Brendan

+0

哦,是的 - 屏蔽非屏蔽中断的想法是邪恶的。我们真的不应该再提起这件事。叹... –

2

端口0x700x71CMOS registers

我在这个主题上找到的最佳名单is from the BOCHS emulator
根据这一列表,代码如下:

mov eax,0x8f ; sets 'NMI disabled ' and 'CMOS RAM index' = 64 
out 0x70,al ; write 
in  al,0x71 ; any write to 0x70 should be followed by an action to 0x71 or the RTC wil be left in an unknown state. 
in  al,0x92 ; read PS/2 system control port A 
or  al,0x2  ; set BIT1 = indicates A20 active 
out 0x92,al ; write PS/2 system control port A 

所以这段代码禁用NMI并设置A20 line活跃状态。最后三行执行Fast A20 Gate


但不知为何,BIOS从端口0x71和0x92连续读取

的原因只是在于

any write to 0070 should be followed by an action to 0071 or the RTC will be left in an unknown state. 

所以先读(读in al,0x71)除了保证这一点以外没有别的用途,因此其结果可以被忽略。

相关问题