在OSDev wiki的一些代码片段中,例如启用A20线,我们使用
例如,在通过旧的键盘控制器方法设置A20线时,整个代码被
cli
中断命令。但在其他一些代码中,我们没有使用它们。例如,在通过旧的键盘控制器方法设置A20线时,整个代码被
cli
和sti
组合包围。我可以想象这必须发生,因为我们通过端口使用键盘通信,键盘中断也可能改变端口上的数据。但这是真的吗?我只是猜测...enable_A20:
cli
call a20wait
mov al,0xAD
out 0x64,al
call a20wait
mov al,0xD0
out 0x64,al
call a20wait2
in al,0x60
push eax
call a20wait
mov al,0xD1
out 0x64,al
call a20wait
pop eax
or al,2
out 0x60,al
call a20wait
mov al,0xAE
out 0x64,al
call a20wait
sti
ret
a20wait:
in al,0x64
test al,2
jnz a20wait
ret
a20wait2:
in al,0x64
test al,1
jz a20wait2
ret
然后,在测试A20线路的代码中(如果它已经激活),中断被禁用,但从未启用。我想不启用它们是一个错误吗?在这种情况下,我可以想象我们必须禁用中断,因为中断可能会跳转到我们在此代码段中修改的内存位置,导致一切崩溃。
check_a20:
pushf
push ds
push es
push di
push si
cli
xor ax, ax ; ax = 0
mov es, ax
not ax ; ax = 0xFFFF
mov ds, ax
mov di, 0x0500
mov si, 0x0510
mov al, byte [es:di]
push ax
mov al, byte [ds:si]
push ax
mov byte [es:di], 0x00
mov byte [ds:si], 0xFF
cmp byte [es:di], 0xFF
pop ax
mov byte [ds:si], al
pop ax
mov byte [es:di], al
mov ax, 0
je check_a20__exit
mov ax, 1
check_a20__exit:
pop si
pop di
pop es
pop ds
popf
ret
另一方面,快速A20门的代码片段没有包含任何中断禁用。但我们也与端口通信(读取和写入)。因此,如果我对键盘控制器的猜测是正确的,那么在我们读取并写回0x92端口之后,某个中断是否会改变其状态呢?因此,基本上我们会覆盖中断处理程序想要更改的内容。
fast_a20_gate:
in al, 0x92
test al, 2
jnz after
or al, 2
and al, 0xFE
out 0x92, al
after:
有没有什么经验之谈可以帮助我轻松决定何时要cli
中断,何时不需要?目前我在做这个决定时感到完全迷失,只能复制我所看到的。
sti
指令。这仅适用于 32/64 位 x86 机器。处理器为 8086 <= processor < 80286,即实模式,是另一个话题,当然。 - cadanilukcli``mov al,2``out 21h,al``sti
- Dirk Wolfgang Glomp