assembly BIOS连续两次从不同端口读取同一寄存器

6qftjkof  于 2023-02-23  发布在  iOS
关注(0)|答案(2)|浏览(188)

我是汇编的新手。当我试图弄清楚BIOS是做什么的时候,我用 * gdb * 来跟踪它。然而,我发现了一些非常奇怪的事情。
代码段如下所示:

[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端口读取?
谢谢大家!

6tqwzwtp

6tqwzwtp1#

IO端口0x70是"CMOS/RTC索引寄存器",IO端口0x71是"CMOS/RTC数据寄存器"。要访问CMOS中的某些内容,您应该设置索引,然后读取/写入数据寄存器。
对于某些RTC芯片,如果您设置了索引,但不读取或写入数据寄存器,则芯片将处于未定义状态。这意味着如果您想稍后设置索引,则必须读取数据寄存器,以避免现在和稍后之间的"未定义状态"。
换句话说读取的值是不相关的-读取会产生副作用,而副作用才是最重要的。

2sbarzqh

2sbarzqh2#

端口0x700x71是CMOS寄存器。
我在这个主题上找到的最好的列表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设置为 active 状态。最后三行实现快速A20门。
我想知道为什么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)除了确保这一点外没有其他用途,因此可以忽略其结果。

相关问题