# Programmation Assembleur/x86/Les interruptions

* Programmation Assembleur/x86
* Introduction
* Registres
* Les flags
* Copie entre registres et mémoire
* Les branchements
* La pile
* Les interruptions
* Opérations arithmétiques et logiques
* Interactions avec les périphériques
* Index
* Conclusion
* 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

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

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

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

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 :
* Si le flag IF est à 1, le processeur appelle le vecteur de traitement de l'interruption déclenchée.
* Puis le processeur poursuit l'exécution après l'instruction HALT.

## Les interruptions matérielles

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 :
* Le contrôleur envoie un signal au processeur sur la ligne INTR,
* Le processeur (Si l'indicateur IF est à 1), signale au PIC qu'il accepte la demande sur la ligne INTA (INTerrupt Acknowledge),
* Le PIC lui envoie le numéro d'IRQ (0 à 7) sur le bus de données,
* Le processeur appelle l'interruption correspondante,
* 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

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

Le tableau suivant décrit brièvement le rôle de chaque interruption.
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

* Cours sur les interruptions
* Les interruptions
* Le microprocesseur 8086