在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' –