IV. LES INTERRUPTIONS
1. Introduction
Le microprocesseur ne peut exécuter qu’une seule
instruction à la fois. Pour connaître son adresse, il
utilise le couple de registres CS:IP dont la valeur est incrémentée
automatiquement. Par conséquent, le code du programme courant
est exécuté de manière linéaire.
Imaginons cependant qu’un événement extérieur
demande l’attention de l’ordinateur, par exemple la
pression d’une touche du clavier. La machine doit pouvoir
réagir immédiatement, sans attendre que le
programme en cours d’exécution se termine. Pour cela,
elle interrompt ce dernier pendant un bref instant, le temps de
traiter l’événement survenu puis rend le
contrôle au programme interrompu.
Une interruption n’est rien d’autre que l’appel
d’une routine spéciale présente en mémoire
appelée ISR (« Interrupt Service Routine »).
Les interruptions se divisent en trois catégories :
-
les interruptions électroniques, par exemple : le clavier
-
les interruptions du BIOS, par exemple : l’accès aux disques
-
les interruptions du DOS, par exemple : l’accès
aux systèmes de fichiers
Comment sont-elles déclenchées ?
Une interruption peut être déclenchée par votre
matériel. C’est ce qui arrive lorsque vous appuyez sur
une touche du clavier. Aucun logiciel n’intervient et le
contrôle est passé directement à la routine qui
gère le clavier : ce sont les interruptions
matérielles.
Les interruptions logicielles
sont quant à elles appelées par des instructions
en langage machine au sein d’un programme. Leur importance est
capitale. Rappelez-vous que contrairement au PASCAL ou au C,
l’assembleur ne dispose pas de fonction préprogrammée.
Chaque instruction doit être directement traduisible en langage
machine.
Mais alors, comment fait-on pour écrire une chaîne de
caractères à l’écran ? Ou bien pour
lire un caractère entré au clavier ?
Eh bien on le fait de la même façon que le DOS lui-même !
On déclenche les interruptions appropriées à
l’aide de l’instruction « INT » du
langage machine. C’est donc une routine du DOS (ou parfois du
BIOS) qui fera tout le travail. Les paramètres (ou leurs
adresses) sont passés dans les registres.
Voici un petit exemple en assembleur qui écrit la lettre ‘A’
à l’écran :
Examinons-le ligne par ligne :
-
l’instruction “MOV DL, ‘A’” demande au processeur
de mettre dans le registre DL le code ASCII de la lettre ‘A’,
c’est-à-dire 65, ou 41h.
-
“MOV AH, 02” : mettre le nombre 2 dans AH.
-
Enfin, la dernière instruction appelle l’interruption numéro
21h. Il existe 256 interruptions. Toutes sont notées en base
hexadécimale.
Explications :
Comme vous aurez très vite l’occasion de vous en rendre
compte, l’interruption 21h est l’interruption du DOS par
excellence. Elle permet d’appeler de nombreuses fonctions très
diverses. Pour cela, il suffit de mentionner leur numéro dans
le registre AH.
Il est très difficile de mémoriser le rôle de chaque
interruption, et a fortiori de chaque fonction ou sous-fonction,
d’autant plus d’elles sont désignées par
des numéros hexadécimaux et qu’elles attendent
des paramètres dans des registres précis. C’est
pourquoi tout programmeur se doit d’avoir à sa
disposition une liste des interruptions pour travailler. Celle de
Ralph Brown est très connue, et vous la trouverez sur
l’Internet.
Revenons à notre exemple. La fonction numéro 2 de l’interruption
21h sert à écrire un caractère à l’écran.
Il faut pour cela écrire le code ASCII du caractère
dans le registre DL et bien sûr placer le nombre 2 dans AH.
Une fois que AH et DL ont été ajustés,
l’interruption 21h peut être appelée à
l’aide de l’instruction INT.
D’autres interruptions ne remplissent qu’une seule tâche. Vous
n’avez donc pas besoin de mettre un numéro de
fonction dans AH. L’appel de l’interruption suffit.
2. La table des vecteurs d’interruptions
A chaque appel d’interruption, l’ordinateur doit pouvoir
trouver l’adresse de l’ISR correspondante. Pour cela, il
dispose de la table des vecteurs
d’interruptions (TVI, ou IVT : « Interrupt
Vector Table »). Cette table est implantée à
l’adresse 0000:0000 c’est-à-dire au début
de la RAM.
La table est organisée comme suit :
Adresse
|
Taille (octets)
|
Valeur
|
0000:0000
|
2
|
Adresse d’offset de l’interruption numéro 0
|
0000:0002
|
2
|
Adresse de segment de l’interruption numéro 0
|
0000:0004
|
2
|
Adresse d’offset de l’interruption numéro 1
|
0000:0006
|
2
|
Adresse de segment de l’interruption numéro 1
|
0000:0008
|
2
|
Adresse d’offset de l’interruption numéro 2
|
0000:000A
|
2
|
Adresse de segment de l’interruption numéro 2
|
0000:000C
|
2
|
Adresse d’offset de l’interruption numéro 3
|
0000:000E
|
2
|
Adresse de segment de l’interruption numéro 3
|
etc…
etc…
etc…
|
0000:03FC
|
2
|
Adresse d’offset de l’interruption numéro 255
|
0000:03FE
|
2
|
Adresse de segment de l’interruption numéro 255
|
La raison pour laquelle les offsets précèdent les adresses
de segment vient du codage en « little endian »
utilisé par INTEL. Les processeurs de cette marque
(contrairement à la plupart des autres, qui travaillent en
« big endian ») ont une représentation
des données en mémoire aussi curieuse qu’insupportable
pour le programmeur : ils placent le poids fort après le
poids faible. Ainsi, le mot 4A28h sera codé 284Ah. Puisque
l’adresse de l’ISR tient sur 32 bits (16 + 16), elle est
représentée comme un double mot («
dword »), donc l’adresse d’offset, qui est le
mot de poids faible, se trouve au début. Eh oui, c’est pénible, mais
il faudra s’y faire !
Remarque :
pour calculer l’adresse de l’entrée dans la TVI
correspondant à l’interruption numéro X, il
suffit de multiplier X par 4.
Exemple :
l’adresse de l’ISR numéro 21h est stockée à
0000:0084.
3. Sauvegarde de l’état des registres lors de l’appel
Un appel d’interruption obéit à certaines règles,
car il est indispensable, une fois l’ISR exécutée,
que le programme interrompu retrouve les registres dans le même
état qu’ils étaient auparavant. Tout doit se
passer comme si l’interruption n’avait jamais eu lieu.
C’est pourquoi avant de faire un saut à l’ISR
pointée par l’entrée correspondante dans la TVI,
l’ordinateur sauvegarde tous les registres sur la pile
courante. Il restaurera leur contenu avant de rendre le contrôle.
Cette procédure est automatique. Il n’incombe pas au
programmeur de prendre toutes ces précautions.
Sommaire
Suite
|