在OSDev wiki for enabling the A20 line的一些代码片段中,我们有cli
中断命令。在其他一些我们没有他们。为什么我们需要在有时启用A20时禁用中断?
E.g.当通过旧的键盘控制器方法设置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
中断,何时不?目前,我完全失去了这个决定,只能复制我能看到的东西。
在进入自举程序时,我通常会立即禁用中断。有很多情况下他们需要被禁用,忘记其中一个可能会导致一个难以追踪的错误。然后,在进入内核时,会进行一些初始化,一旦IDT设置完成,将执行'sti'。这仅适用于32/64位x86机器。 8086 <=处理器<80286,即实模式,当然是不同的话题。 – Downvoter
是的,这是必要的,你不能承受硬件中断处理程序也与端口0x60猴子。它也被键盘控制器使用。第二个片段*会重新启用中断,popf指令会恢复它。 –
我喜欢拆开键盘IRQ:'cli'' mov al,2''out 21h,al''sti' –