Modalità reale, interruzione della sostituzione vettoriale Arresto anomalo
-
20-08-2019 - |
Domanda
Sto cercando di saperne di più su come funzionano davvero i sistemi sotto tutta la bella grafica in cima. Quindi sto attualmente giocando con la memoria nei 512byte che il BIOS carica all'avvio, non posso davvero chiamarlo bootloader al momento immagino. Ad ogni modo, sto sostituendo un vettore di interruzione ma ho dei problemi con esso. Dopo aver sostituito l'interrupt 09h (la tastiera) funziona correttamente, alla pressione del tasto viene emesso "Memory messing". Ma poi niente. Ogni pressione successiva dei tasti non fa nulla. Non so se il sistema si sta arrestando in modo anomalo o se mi manca qualcosa dal mio gestore, ecco il codice:
jmp start
times 100 db 0 ; Cleared space for stack
start:
xor ax, ax
mov ax, start
sub ax, 80
mov sp, ax
mov al, 0x09 ; Interupt number
mov bl, 4
mul bl
mov bx, ax
xor ax, ax
mov es, ax
mov [es:bx], word prints ; My interupt handler
add bx, 2
mov [es:bx], word 0x00
bloader:
jmp bloader
prints:
cli
push ax
push bx
push si
mov si, msg ; Message to print
mov bl, 0x07
mov bh, 0x00
printnb:
lodsb ; Grab byte from message
cmp al, 0 ; End of message
je printf
mov ah, 0x0E
int 0x10 ; Print byte
jmp printnb
printf:
mov al, 0x20
out 0x20, al ; Inform interupt controller interupt has been handled
pop si
pop bx
pop ax
sti
iret ; Interupt return
msg db "Memory messing",0
times 510 - ($ - $$) db 0
dw 0xAA55
Soluzione
È passato molto tempo da quando ho lavorato sulla gestione degli interrupt di tastiera, ma penso che ciò che ti manca sia effettivamente gestire l'hardware della tastiera in modo da cancellare la condizione di interrupt ed essere pronto a generare un altro interrupt.
Qualcosa del tipo:
in al, 60h ; Read input buffer
potrebbe essere tutto ciò che serve.
Se avrò la possibilità, vedrò se ho delle vecchie note o del codice in giro da quando ho scritto i driver della tastiera.
Altri suggerimenti
La mia ipotesi (non ho mai scritto un gestore di interrupt di tastiera) è che devi anche parlare con l'hardware della tastiera, per recuperare la sequenza di tasti (altrimenti la tastiera non saprà quando generare un interrupt successivo).
Ho trovato un altro problema. Se impostiamo un nuovo vettore di interrupt per un ISR con due istruzioni di spostamento separate, è possibile che tra queste due istruzioni di mov si verifichi un interruzione e quindi ottenga l'indirizzo da un vettore rotto con una parte della vecchia posizione e il altra parte della nuova posizione dell'ISR. Ma in questa posizione non c'è ISR, nessuna istruzione per una FINE di interruzione e nessuna istruzione iret.
Per prevenire eventi così brutti dobbiamo mettere un cli e una sti attorno a quelle istruzioni di spostamento per impostare un nuovo vettore di interrupt.
cli
mov [es:bx], word prints ; My interupt handler
mov [es:bx+2], word 0x00
sti
Dirk
Questa è solo un'ipotesi selvaggia, ma forse il problema è che stai chiamando int 10h dal gestore int 9h. Prova a scrivere direttamente nella memoria dello schermo (basta incrementare il byte a 0b800h: 0 e selezionare il carattere in alto a sinistra sullo schermo). Se viene incrementato per ogni pressione di un tasto, non dovresti chiamare int 10h da int 9h.