Aller au contenu

Programmation Assembleur/x86/Les interruptions

Un livre de Wikilivres.
Programmation Assembleur/x86
Modifier ce modèle


Une interruption, comme son nom l'indique, interrompt l'exécution normale des instructions du programme pour en exécuter d'autres avant de revenir au fonctionnement normal.

Une interruption peut survenir de deux manières :

  • Elle peut être sollicitée par le matériel pour effectuer un traitement (lire une touche du clavier par exemple). Dans ce cas le matériel déclenche une IRQ (Interrupt ReQuest) possédant un numéro propre au port auquel le matériel est connecté. Chaque IRQ correspond à une interruption particulière. Il s'agit d'une interruption matérielle.
  • Elle peut être sollicitée par le logiciel en cours d'exécution avec l'instruction INT. Il s'agit d'une interruption logicielle.

Numéro d'interruption

[modifier | modifier le wikicode]

Chaque interruption possède un numéro compris entre 0 et 255, car codé sur 1 octet.

L'instruction INT possède un seul opérande : le numéro de l'interruption à appeler.

Vecteurs d'interruption

[modifier | modifier le wikicode]

Chaque interruption correspond à une routine dont l'adresse mémoire est stockée dans la table des vecteurs d'interruption. Cette table est stockée en mémoire à l'adresse 0000:0000, et stocke pour chaque vecteur, l'adresse de la routine à appeler, sur 4 octets (offset puis segment, chacun sur 2 octets).

Appel à une interruption

[modifier | modifier le wikicode]

L'appel explicite (interruption logicielle par l'instruction INT) ou implicite (interruption matérielle par IRQ) à une interruption de numéro n se déroule de la manière suivante :

  1. Sauvegarder l'adresse de retour :
    1. Empiler le registre des indicateurs (EFLAGS),
    2. Empiler le registre de segment CS,
    3. Empiler le registre d'instruction IP / EIP,
  2. Appeler le vecteur d'interruption n :
    1. Placer la valeur de 0000:4*n dans IP / EIP,
    2. Placer la valeur de 0000:4*n+2 dans CS,
    3. Mettre les indicateurs IF (Interrupt Flag) et TF (Trap Flag) à 0, afin d'éviter une autre interruption durant l'interruption en cours,
  3. Exécuter la routine...
  4. ...Jusqu'à trouver l'instruction IRET (Interrupt RETurn) :
    1. Dépiler la valeur du registre d'instruction IP / EIP,
    2. Dépiler la valeur du registre de segment CS,
    3. Dépiler la valeur du registre des indicateurs (EFLAGS).

Durant le traitement de l'interruption, l'exécution de la routine ne peut pas être interrompue par une autre interruption, excepté par une interruption non masquable déclenchée sur la ligne NMI (Non Masquable Interrupt) du processeur, ou bien si la routine remet le flag IF (Interrupt Flag) à 1.

Le codage de l'instruction INT se fait sur deux octets : le premier est CD (en hexadécimal) et le second est le numéro de l'interruption appelée (0 à 255). Il existe une version courte pour INT 3 (breakpoint) sur un octet valant CC en hexadécimal (Mnémotechnique : Cesser l'exécution). Cela permet aux débogueurs de placer des points d'arrêts en remplaçant l'octet à l'adresse cible par CC, en gardant un seul octet d'origine en mémoire par point d'arrêt. Cette technique n'est toutefois pas possible pour du code situé en ROM (lecture seule).

L'instruction INTO permet d'appeler l'interruption 4 seulement si l'indicateur de débordement (OF : Overflow Flag) est à 1. Elle est en général utilisée après une opération arithmétique pour traiter une erreur.

Attendre l'arrivée d'une interruption

[modifier | modifier le wikicode]

L'instruction HALT suspend l'exécution des instructions par le processeur, jusqu'à l'arrivée d'une interruption. Lors de l'arrivée d'une interruption :

  1. Si le flag IF est à 1, le processeur appelle le vecteur de traitement de l'interruption déclenchée.
  2. Puis le processeur poursuit l'exécution après l'instruction HALT.

Les interruptions matérielles

[modifier | modifier le wikicode]

Le processeur possède trois lignes d'entrée interrompant le cours de l'exécution normale :

  • La ligne RESET activée au démarrage du système. Le processeur initialise les registres à leur valeur par défaut (0000, sauf CS qui vaut FFFF).
  • La ligne INTR (INTeRrupt) est activée par le contrôleur d'interruption (PIC : Programmable Interrupt Controller) quand le matériel demande une interruption. Le contrôleur permet également de masquer certaines interruptions (ignorer les demandes).
  • La ligne NMI (Non Masquable Interrupt) est activée, en général, quand un problème matériel grave est détecté.

Le contrôleur d'interruption peut recevoir 8 demandes d'interruption. Il gère leur priorité (quelle interruption traiter en premier quand plusieurs demandes arrivent). Dès qu'une demande d'interruption lui parvient :

  1. Le contrôleur envoie un signal au processeur sur la ligne INTR,
  2. Le processeur (Si l'indicateur IF est à 1), signale au PIC qu'il accepte la demande sur la ligne INTA (INTerrupt Acknowledge),
  3. Le PIC lui envoie le numéro d'IRQ (0 à 7) sur le bus de données,
  4. Le processeur appelle l'interruption correspondante,
  5. La routine de traitement de l'interruption doit signaler au PIC la fin du traitement d'interruption, pour lui permettre de traiter la suivante.

Masquage des interruptions

[modifier | modifier le wikicode]

Les interruptions déclenchées par la ligne INTR du processeur sont masquables : elles sont ignorées si le flag Interrupt est à 0. Deux instructions permettent de modifier cet indicateur :

  • L'instruction CLI (CLear Interrupt) positionne l'indicateur IF à 0 (interruptions ignorées),
  • L'instruction STI (SeT Interrupt) positionne l'indicateur IF à 1 (interruption autorisées).

Les interruptions déclenchées par la ligne NMI (Non Masquable Interrupt) du processeur ne sont pas masquables (comme le nom de la ligne l'indique en anglais), la valeur du flag Interrupt est ignorée. Ces interruptions sont donc réservées pour notifier des problèmes matériels graves.

Liste des interruptions

[modifier | modifier le wikicode]

Le tableau suivant décrit brièvement le rôle de chaque interruption.

Numéro Déclenchement Description
00 Division par 0. Traitement de l'erreur quand une division par 0 survient.
01 Avant chaque instruction quand TF=1 Trap : Exécution pas à pas.
02 NMI Non Masquable Interrupt : appelée quand un problème matériel grave est détecté.
03 INT 3 Breakpoint : Point d'arrêt dans le code.
04 INTO Débordement numérique (Overflow).
05 INT 5 Copie d'écran. Interruption appelée quand la touche "Impécr" est appuyée.
06
07
08 IRQ0 Timer
09 IRQ1 Clavier
0A IRQ2 PIC2
0B IRQ3 Port série 2 (COM2)
0C IRQ4 Port série 1 (COM1)
0D IRQ5 Disque dur
0E IRQ6 Disquette
0F IRQ7 Port parallèle (LPT1) : imprimante

Les autres interruptions (10 à FF) sont déclenchées logiciellement avec l'instruction INT pour appeler des fonctions du systèmes d'exploitation, du BIOS, ou de programmes chargés en mémoire. Par exemple, sous DOS, l'interruption 21 (hex) sert à appeler les fonctions du DOS (accès aux fichiers, gestion de la console, ...) ; la fonction étant indiquée par la valeur du registre AX.

Références externes

[modifier | modifier le wikicode]