Mode réel, remplacement du vecteur d'interruption
-
20-08-2019 - |
Question
J'essaie d'en apprendre davantage sur la façon dont les systèmes fonctionnent vraiment sous tous les jolis graphismes du dessus. Donc, je joue actuellement avec la mémoire dans les 512 octets que le BIOS charge au démarrage, je ne peux pas vraiment l'appeler un chargeur de démarrage pour le moment. Quoi qu'il en soit, je remplace un vecteur d'interruption, mais j'ai des problèmes avec ce dernier. Après le remplacement de l'interruption 09h (le clavier), il fonctionne correctement. Une pression sur la touche, "Message mémoire", est émise. Mais alors rien. Chaque pression sur la touche après ne fait rien. Je ne sais pas si le système est en panne ou s'il me manque quelque chose de mon gestionnaire, voici le code:
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
La solution
Cela fait longtemps que je n’ai pas travaillé sur les interruptions au clavier, mais je pense que ce qui vous manque, c’est de gérer le matériel du clavier, ce qui effacera la condition d’interruption et sera prêt à générer une autre interruption.
Quelque chose comme:
in al, 60h ; Read input buffer
pourrait être tout ce qu'il faut.
Si j'en ai l'occasion, je verrai si j'ai d'anciennes notes ou du code qui traînent depuis le passé lorsque j'ai écrit les pilotes de clavier.
Autres conseils
Mon hypothèse (je n'ai jamais écrit de gestionnaire d'interruption de clavier) est que vous devez également parler au matériel du clavier pour récupérer la frappe (sinon le clavier ne saura pas quand générer une prochaine interruption).
J'ai trouvé un autre problème. Si nous définissons un nouveau vecteur d'interruption pour un ISR avec deux instructions de déplacement distinctes, il est possible qu'entre ces deux instructions de déplacement, une interruption se produise et qu'il obtienne l'adresse d'un vecteur rompu avec une partie de l'ancien emplacement et le autre partie du nouvel emplacement de l'ISR. Mais à cet endroit, il n'y a pas de rapport ISR, pas d'instructions pour une fin d'interruption et également pas d'instruction iret.
Pour éviter de tels événements, nous devons placer un clic et un sti autour de ces instructions de déplacement afin de définir un nouveau vecteur d'interruption.
cli
mov [es:bx], word prints ; My interupt handler
mov [es:bx+2], word 0x00
sti
Dirk
Ceci n’est qu’une mauvaise idée, mais le problème est peut-être que vous appelez int 10h à partir du gestionnaire int 9h. Essayez d'écrire directement dans la mémoire d'écran (augmentez simplement l'octet à 0b800h: 0 et vérifiez le caractère en haut à gauche de l'écran). Si la touche est incrémentée, vous ne devriez pas appeler int 10h à partir de 9h.