汇编 – 有时为什么我们需要在启用A20时禁用中断?
在OSDev wiki
for enabling the A20 line的一些代码中,我们有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,0xAE out 0x64,al call a20wait sti ret a20wait: in al,0x64 test al,2 jnz a20wait ret a20wait2: in 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中断,何时不能?目前我完全迷失在这个决定中,只是可以复制我能看到的东西. 解决方法
当您与键盘控制器通信时,您肯定希望将整个命令作为不间断的序列发送给它.所以你必须阻止任何人打扰你(!)你.
fast_a20_gate没有那个问题.它不是一个序列,而只是一个命令 – 实际上是一个位.如果有人碰巧干扰并翻转了这一点,你仍然会在最后设置它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |