LES INTERRUPTIONS

 

I. Introduction sur les interruptions

Il faut savoir qu’il existe 256 adresses d'interruptions différentes, que ce soit des interruptions de type matériel ou de type logiciel. Pour traiter une interruption, le CPU exécute un programme spécial, appelé gestionnaire d'interruption dont l’adresse est stockée dans une table qui permet donc de faire la correspondance entre le numéro de l’interruption et son adresse réelle (stockée sur 4 octets). Ainsi, quand vous appelez l’interruption numéro 10 du BIOS, vous sautez à une adresse mémoire, adresse contenue dans la table de correspondance. Les microprocesseurs de la famille 8086 ont une table des vecteurs d’interruption commençant à l’adresse 0000:0000, qui s’étend sur 1024 octets (4*256).

Extrait de la table des correspondances :

Adresse

Interruption

Adresse du vecteur d'interruption

Description

03FCh à 03FFh

255

02 82:0F 00

 

...

...

...

 

000Ch à 000Fh

3

00 07:04 65

 

0008h à 000Bh

2

09 56:00 16

 

0004h à 0007h

1

00 07:04 65

Trappe pas a pas materielle

0000h à 0003h

0

00CA:0F9E
Division par zero, materielle
 
Pour avoir une liste complète :
http://www.ctyme.com/intr/int.htm
http://www.cs.cmu.edu/~ralf/files.html

 

Interruptions logicielles

Les interruptions logicielles sont celles qui sont déclenchés par un programme. Pour déclencher une interruption en asm, il suffit d’utiliser le mot clé int. Une fonction(du BOIS ou du DOS par exemple) est ainsi appelée

Interruptions matérielles

On dit qu’une interruption est matérielle lorsqu'elle est demandée par un composant matériel du PC (un périphérique qui a besoin d'utiliser les ressources du système par exemple). Avant de parler des interruptions, parlons un peu des périphériques eux-mêmes.

Les périphériques ont parfois besoin d'échanger des informations avec le processeur, c'est pourquoi on leur assigne des adresses par lesquelles ils peuvent envoyer et recevoir des informations. Ces adresses sont appelées ports d'E/S (Entrée/Sortie) ou I/O (Input/Output) en anglais.

Pour éviter tous conflits matériels, il faut savoir qu’il ne peut y avoir qu'une adresse unique par périphérique. Par exemple, 060h pour le clavier.

Voici une liste de quelques adresses de base courantes : IO port addresses.txt

Après avoir présenté le périphérique, parlons maintenant des différentes solutions pour l’échange de données entre l’unité centrale et les périphériques :

1. Sonder le port, donc lire l'état du port à intervalles fixes, pour déterminer si des données ont bien été reçues, ou si un changement d'état a eu lieu. L’avantage de cette méthode est bien sûr la simplicité de programmation, ce qui ne serait pallier l’inconvénient majeur : utilisation de beaucoup de temps processeur.

2. DMA (accès direct à la mémoire)

3. Utiliser des interruptions (matérielles), ce qui évite de gaspiller du temps à sonder les ports.

C’est sur cette dernière solution que nous allons nous arrêtez un peu…

II. Interruptions matérielles

1. Demande d’interruption (Interupt ReQuest ou IRQ)

Lorsqu’un port d’Entrée/Sortie à quelle chose à dire, il envoie alors une demande d’interruption (IRQ) directement au processeur. Le processeur arrête alors l’instruction qu’il était en train d’exécuter si toutefois l’interruption concernée n’a pas été masquée, c’est à dire rendu impossible pendants un laps de temps. Ainsi, si l’interruption est autorisée, le processeur sauvegarde le contenu de ses registres (dans la pile), et exécute la routine d’interruption correspondante. Une fois la routine d’interruption terminée, le processeur restaure le contenu de la pile, et reprend sa tâche, là où il s’était arrêté.

Ainsi, les périphériques ont un numéro d'interruption, que l'on appelle IRQ (Interruption resquest, ce qui signifie "requête d'interruption"). Ces IRQ sont contrôlés par un contrôleur d'interruption qui sélectionne l’interruption prioritaire. Sur un 8086, ce contrôleur acceptait 8 interruptions différentes, mais sur les processeurs actuels, ce nombre est porté à 16 interruptions, allant de 0 à 15.

Table des interruptions matérielles (8086)

IRQ

Périphérique

0

Horloge interne

1

Clavier

2

Libre

3

COM 2

4

COM 1

5

Contrôleur Disque dur

6

Contrôleur Disquette

7

Interface parallèle

 

Table des interruptions matérielles (Pentium)

IRQ

Périphérique

0

Horloge interne

1

Clavier

2

Contrôleur d'interruptions programmable
Renvoi vers les IRQ 8 à 15

3

COM 2/COM 3

4

COM 1/COM 4

5

Libre

6

Contrôleur Disquette

7

Interface parallèle

8

CMOS (Horloge temps réel)

9

Libre

10

Libre

11

Libre

12

Port sourie PS2

13

Coprocesseur mathématique

14

Disque dur primaire IDE

15

Disque dur secondaire IDE

Il semble aussi évident que 2 périphériques ne peuvent avoir le même IRQ, car sinon, le système risque de s’emmêler les pinceaux et de ne pas savoir à qui il doit donner la priorité, ce qui entraîne encore une fois un conflit matériel.

2. Le contrôleur d’interruption

Le contrôleur d’interruptions programmable (Programmable Interupt Controler ou PIC) gère les interruptions matérielles. La plupart des PC en ont deux, situées à différentes adresses. L’un gère les interruptions 0 à 7 et l’autre est en cascade par rapport au premier, utilisant IRQ2, et gère les interruptions 8 à 15, ce qui donne un total de 15 lignes d’interruption.

Il faut savoir que la plus grande partie de l’initialisation du PIC est effectuée par le BIOS, ce qui décharge le programmeur de cette tâche. Il est bien sur possible d’activer ou de masquer une interruption ou encore d’implémenter une nouvelle routine d’interruption (ISR) par programme (http://perso.wanadoo.fr/peggs/interupt.htm pour plus d’informations).

Prenons comme exemple, l’implémentation d’une ISR pour le clavier (interruption 09h). Pour changer le vecteur d’interruption, il nous faut suivre les étapes suivantes :
-sauvegarder l'ancien vecteur de l'interruption 09h
-le remplacer par l'adresse du gestionnaire d'interruption
-exécuter son code
-...
-restaurer l'ancien vecteur d'interruption (sinon, vous ne pourrez faire que ce que votre propre gestionnaire vous permet de faire. S’il vous permet seulement d’afficher un message quand vous appuyez sur la touche ‘A’, comme ferez vous pour quitter votre application avec Ctrl+C en cas de problème ?)

Pour lire le contenu d'un vecteur d'Interruption en assembleur, utiliser la fonction 35h de l’int 21h et pour modifier le vecteur d'Interruption, utiliser la fonction 25h.

Ensuite, il faut écrire votre procédure gestionnaire d'interruption suivant le schéma :
-lire le port 60h
- code
-renvoie 20h au port 20h
-IRET

En asm, ca donne :

driver:
cli ; empêche l' execution des interruptions masquables
push ax
... ; code
mov al,0x20
out 0x20,al ; envoie l'EOI au pic
pop ax
sti ; permet aux interruptions masquables d'être exécutées
iret

L’instruction EOI (End of Interrupt ou Fin de l’interruption) est indispensable lorsque vous venez de modifier le vecteur d’interruption dans un programme puisqu’elle permet de réinitialiser le In Service Register.

Remarque : si vous voulez voir un exemple concret, regarder le code source du pong fournit sur ce site.


retour