Documente Academic
Documente Profesional
Documente Cultură
2011-2012
ayrel
Pierre-Louis C
www.cayrel.net
IUT de Saint-Etienne
1 Présentation du module 7
1.1 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Pré-requis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Intervenants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Introduction 9
2.1 (Micro) processeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.1 Dénition et rôle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.2 Bref historique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Microcontrôleurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Codage de l'information 13
3.1 Information discrète . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Représentation des nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3 Conversions d'entiers naturels . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3.1 Passage d'une base quelconque à la base 10 . . . . . . . . . . . . . . . . . 14
3.3.2 Passage de la base 10 à une base quelconque . . . . . . . . . . . . . . . . 14
3.4 Représentation des nombres dans les processeurs . . . . . . . . . . . . . . . . . . 17
3.4.1 Limitation de la taille . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.2 Les entiers logiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.3 Les entiers arithmétiques . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4.4 Codage des nombres réels (norme IEEE 754) . . . . . . . . . . . . . . . . 21
3.4.5 Codage des caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.4.6 Code BCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.4.7 Lien avec les types du langage C . . . . . . . . . . . . . . . . . . . . . . 24
3
4 TABLE DES MATIÈRES
7 Les pointeurs 55
7.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.2 Utilisation des pointeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.3 échange de deux variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
8 Interruptions 59
8.1 Fonctionnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
8.2 Usages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.2.1 Entrées-sorties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.2.2 Multi-tâche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
TABLE DES MATIÈRES 5
8.3 Remarques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.3.1 Priorité des interruptions . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.3.2 Interruptions contre polling . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.4 Chien de garde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.5 Interruption matérielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
8.5.1 Description vulgarisée . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
8.5.2 Les IRQ sur les architectures compatibles IBM PC . . . . . . . . . . . . 63
6 TABLE DES MATIÈRES
Chapitre 1
Présentation du module
1.1 Objectifs
1. Comprendre quel type d'information est traitée dans un système à processeur ;
4. Être capable d'écrire un programme en langage de haut niveau pour une cible à micro-
processeur ou à microcontrôleur.
1.2 Pré-requis
II1 : Algorithmie et syntaxe du langage C ;
ENSL1 : Conception de systèmes logiques.
1.3 Intervenants
ayrel : Cours/TD/TP
Pierre-Louis C
Florent Bernard : TP
7
8 CHAPITRE 1. PRÉSENTATION DU MODULE
Chapitre 2
Introduction
9
10 CHAPITRE 2. INTRODUCTION
Avantages principaux :
beaucoup plus petit et léger (comparé au tube électronique) : permet la miniaturisation
des composants électroniques ;
robuste, able et ecace : comparé aux tubes à vide (fragile, préchauage), relais méca-
nique (gestion de l'anti rebonds) ⇒ limitation de la fréquence de commutation ;
fonctionne avec des tensions faibles : faible consommation et permet le fonctionnement sur
pile (fonctionnement autonome).
années 1950 : Intégration de plusieurs transistors sur une même surface de matériau semi-
conducteur : naissance du circuit intégré.
Plusieurs niveaux d'intégration :
SSI (Small Scale Integration) petite : inférieur à 12 ;
MSI : (Medium Scale Integration) moyenne : 12 à 99 ;
LSI : (Large Scale Integration) grande : 100 à 9999 ;
VLSI : (Very Large Scale Integration) très grande : 10000 à 99999 ;
ULSI : (Ultra Large Scale Integration) ultra grande : 100000 et plus.
Rappel : Dès qu'il a été possible d'intégrer susament de transistors sur un même circuit
intégré an de réaliser un processeur, le terme microprocesseur a supplanté celui de proces-
seur.
Avantages : le fait de pouvoir intégrer les transistors le composant sur un même circuit semi-
conducteur, permet des temps de commutation plus court (du fait de la dimension réduite
et de la réduction du nombre de capacités parasites des portes logiques) augmentant ainsi la
fréquence de fonctionnement des microprocesseurs synchrones de quelques dizaines de MHz
à plusieurs GHz.
1971 : Apparition du premier microprocesseur : Intel 4004 ;
1974 : Apparition du premier microprocesseur employé couramment : Intel 8080 ;
1975 Loi de Moore :
1. La Loi de Moore a été exprimée en 1965 dans Electronics Magazine par Gordon Moore,
ingénieur de Fairchild Semiconductor, un des trois fondateurs d'Intel. Constatant que
la complexité des semiconducteurs proposés en entrée de gamme doublait tous les ans
à coût constant depuis 1959, date de leur invention, il postulait la poursuite de cette
croissance (en 1965, le circuit le plus performant comportait 64 transistors). Cette
augmentation exponentielle fut rapidement nommée Loi de Moore ou, compte tenu de
l'ajustement ultérieur, Première loi de Moore.
2. En 1975, Moore réévalua sa prédiction en posant que le nombre de transistors des mi-
croprocesseurs (et non plus de simples circuits intégrés moins complexes car formés de
composants indépendants) sur une puce de silicium double tous les deux ans. Bien qu'il
ne s'agisse pas d'une loi physique mais juste d'une extrapolation empirique, cette pré-
diction s'est révélée étonnamment exacte. Entre 1971 et 2001, la densité des transistors
a doublé chaque 1,96 année. En conséquence, les machines électroniques sont devenues
de moins en moins coûteuses et de plus en plus puissantes.
3. Une version commune, variable et sans lien avec les énoncés réels de Moore est : quelque
chose double tous les dix-huit mois, cette chose étant la puissance, la capacité, la vitesse
et bien d'autres variantes mais très rarement la densité des transistors sur une puce. Ces
pseudo lois de Moore sont celles le plus souvent diusées, car elles eurissent dans des
publications grand public et sur de nombreux sites Internet. Leur seul point commun
est donc ce nombre de dix-huit mois, qu'on ne trouve pourtant dans aucun des deux
énoncés de Moore.
2.1. (MICRO) PROCESSEURS 11
Même si on peut avoir l'impression (réelle) qu'il y a eu de grandes évolutions tant au niveau de la
complexité, la taille, la construction et la forme générale des processeurs au cours des soixantes
dernières années, il faut noter que la conception et les fonctions de base n'ont pas beaucoup
changé. La plupart des architectures actuelles peuvent être décrites comme de machines à
programme enregistré de Von Neumann.
12 CHAPITRE 2. INTRODUCTION
2.2 Microcontrôleurs
Un microcontrôleur est un circuit intégré qui rassemble les éléments essentiels d'un ordinateur :
(micro)processeur ;
mémoires (morte, vive) ;
unités périphériques ;
interfaces d'entrées/sorties.
Les caractéristiques principales d'un microcontrôleur sont :
haut degré d'intégration ;
faible consommation électrique : quelques mW en fonctionnement, quelques nW en veille ;
vitesse de fonctionnement plus faible (dizaine à centaine de MHz) que les microprocesseurs
plus polyvalent qu'on trouve dans nos ordinateurs personnels ;
coût réduit.
Les microcontrôleurs, ont permis de démocratiser l'usage de l'informatique dans un grand
nombre de produits et de procédés. Ils sont de fait fréquemment utilisés dans les systèmes
embarqués comme les contrôleurs des moteurs automobiles, les télécommandes, les appareils de
bureau, l'électroménager, les jouets, la téléphonie mobile, etc . . ..
Certains constructeurs se sont spécialisés dans des secteurs d'activités précis, par exemple :
Innéon : secteur automobile ;
Philips : électroménager ;
Texas Instruments : basse consommation, portabilité.
Plus généralement, un processeur doit pouvoir traiter plusieurs types d'information diérents
(texte, nombres, vidéo, audio, . . .). Cette information, intelligible pour nous, doit être transfor-
mée en information intelligible par le processeur an qu'il puisse la traiter.
Cette étape est appelée codage de l'information et transforme notre information en une suite
de 0 ou 1, qui est la seule information intelligible par le processeur.
Outre le fait que l'information binaire représente les états possibles d'un transistor, elle présente
l'avantage de rendre particulièrement simple les opérations arithmétiques de base (addition,
multiplication binaire).
Exemple 1. Donner les tables d'addition et de multiplication opérant sur des bits.
2 × 1000 + 0 × 100 + 1 × 10 + 1 × 1
ou encore
2 × 103 + 0 × 102 + 1 × 101 + 1 × 100
13
14 CHAPITRE 3. CODAGE DE L'INFORMATION
𝑛
∑
𝑎𝑛 𝑎𝑛−1 . . . 𝑎1 𝑎0 = 𝑎𝑖 𝑏 𝑖
𝑖=0
= 𝑎𝑛 𝑏𝑛 + 𝑎𝑛−1 𝑏𝑛−1 + ⋅ ⋅ ⋅ + 𝑎1 𝑏 + 𝑎0
Exemple 3.
(12101121)3 = 1 × 37 + 2 × 36 + 1 × 35 + 1 × 33 + 1 × 32 + 2 × 31 + 1 × 30
= 2187 + 2 × 729 + 243 + 27 + 9 + 2 × 3 + 1
= (3931)10
Exemple 5. Si 1 bit est disponible, on peut représenter les états 0 et 1, soit 2 états.
Si 2 bits sont disponibles, on peut représenter les états :
0 0
0 1
1 0
1 1
soit 4 états.
Si 3 bits sont disponibles, 2 bits représentent les 4 états précédents et on peut rajouter un
troisième bit à 0 ou un troisième bits à 1 pour donner 2 × 4 = 8 états :
0 0 0 1 0 0
0 0 1 1 0 1
0 1 0 1 1 0
0 1 1 1 1 1
Conséquence : à chaque ajout d'un bit, on multiplie par deux le nombre d'états que l'on peut
représenter.
Avec 𝑛 bits, on va donc pouvoir représenter 2𝑛 états.
𝑥 = 𝑎𝑛−1 2𝑛−1 + ⋅ ⋅ ⋅ + 𝑎1 2 + 𝑎0
Les bits 𝑎0 , 𝑎1 , . . ., 𝑎𝑛−1 composant l'entier logique n'ont pas tous la même importance. Il est
clair que si 𝑎0 change de 0 à 1 (ou l'inverse), l'ordre de grandeur de l'entier ne va pas être
modié. En revanche si 𝑎𝑛−1 change de 0 à 1 (ou l'inverse), l'ordre de grandeur de l'entier
logique va être grandement modié.
On parle de poids associés aux bits composant l'écriture des entiers logiques. Ces poids sont les
puissances de 2
associées à chaque bit.
Ainsi, 𝑎7 27 = 128. C'est à dire que si 𝑎7 change de valeur, l'entier logique associé
est de poids
7
change de valeur de ±2 = ±128, alors que si 𝑎0 change de valeur, l'entier logique associé change
0
de valeur de ±2 = ±1.
Les poids forts sont donc les plus grandes puissances de 2 et les poids faibles les plus petites
puissance de 2.
Remarque 2. On utilisera souvent le terme MSB (Most Signicant Bit), pour parler du bit
signicatif de poids le plus élevé d'un entier logique et de LSB (Least Signicant Bit), pour
parler du bit de poids le moins élevé d'un entier logique.
Remarque 3. La plupart du temps, les entiers logiques sont représentés avec le bit de poids le
plus fort à gauche et le bit de poids le plus faible à droite.
On parle de représentation Little Endian , le plus petit à la n.
Dans le cas contraire, on parle de représentation Big Endian , le plus fort à la n.
3.4. REPRÉSENTATION DES NOMBRES DANS LES PROCESSEURS 19
Ainsi, un groupe de 8 bits forme un octet (Byte en anglais) et permet de représenter 28 = 256
états (par exemple : les 256 caractères possibles de la table ASCII).
Les capacités des mémoires sont souvent données sous la forme de groupements d'octets.
Exemple 8. Conversions :
binaire −→ octale :
(110101)2 = ((110)2 (101)2 )8
= (65)8 (= 6 × |{z} 23 +5)
8
binaire −→ hexadécimale :
(10110101)2 = ((1011)2 (0101)2 )16
= (𝐵5)16 (= 11 × |{z} 24 +5)
16
hexadécimale −→ octale :
(𝐵5)16 = ((1011)2 (0101)2 )16
= ((010)2 (110)2 (101)2 )8
= (265)8 (= 2 × 82 + 6 × 8 + 5)
20 CHAPITRE 3. CODAGE DE L'INFORMATION
Opérations arithmétiques
Elles s'eectuent de la même façon qu'en base 10, dès qu'on atteint ou on dépasse la valeur de
la base 𝑏, une retenue se reporte sur le chire de poids directement supérieur.
0 𝑎𝑛−2 . . . 𝑎1 𝑎0
1. Entiers positifs ou nuls :
|{z} | {z }
signe bits signicatifs
Les 𝑛−1 bits signicatifs sont codés en binaire naturel (càd : de la même manière que
pour les entiers logiques, bit de poids fort à gauche).
Le plus grand entier positif qu'il est possible de représenter est :
+2𝑛−1 − 1 = (0∣ 1| . {z
. . 11})2
𝑛−1
2. Entiers négatifs :
L'idée la plus naturelle serait de coder le signe − par un bit de signe à 1 et de coder
la valeur absolue de l'entier négatif en représentation binaire naturelle en utilisant les
𝑛−1 bits restants. Cette méthode de codage, dîte par signe/amplitude n'est pas du tout
adaptée au calcul arithmétique.
Pour avoir une représentation des entiers négatifs utilisable pour les opérations arithmé-
tiques, on utilise la méthode du complément à 2 (vue en ENSL1) :
(a) On prend le complément à 1 de l'entier arithmétique dont on veut l'opposé (on
inverse tous les bits de sa représentation, y compris le bit de signe puisque lorsqu'on
prend l'opposé, le signe change).
(b) On ajoute 1
Sur 𝑛 bits, on peut donc représenter 2𝑛 entiers, de −2𝑛−1 à 2𝑛−1 − 1.
Exemple 12. Donner la représentation en complément à 2 des entiers négatifs suivant :
(a) Sur 4 bits, (−7)10
(b) Sur 8 bits, (−7)10
(c) Sur 8 bits, (−128)10
(d) (−1027)10 , de combien de bits avez vous besoin pour stocker ce nombre ?
Remarque 8. Lorsque le nombre de bits sur lequel eectuer le codage n'est pas précisé,
il convient de prendre le nombre de bits minimal nécessaire au codage.
Exemple 13. Opérations, cohérence :
(a) En utilisant la méthode complément à 2, prenez l'opposé de (−7)10 . Que constatez-
vous ?
(b) En utilisant les représentations des entiers arithmétiques sur 8 bits, eectuez les
opérations :
i. (115)10 − (37)10
ii. (7)10 − (98)10
1
3, 25 = 3 +
|{z} 4
partie entière
|{z}
partie fractionnaire
= 1 × 21 + 1 × 20 + 0 × 2−1 + 1 × 2−2
= (11, 01)2
qui peut aussi se représenter par +1, 101 × 21 .
Comme il y a de nombreuses façons de représenter un même nombre réel, il a été proposé
plusieurs normalisations, dont la plus utilisée est la norme IEEE 754.
Dans cette norme, un nombre réel non nul s'écrit
𝑠 1,𝑀 ×2𝑛
0
|{z} 10000000
| {z } 10100000000000000000000
| {z }
signe positif 127+1 mantisse
Important : même si 7, 34 est un nombre décimal exact, il n'est pas possible d'obtenir une
représentation exacte de ce nombre selon la norme IEEE 754 avec 32 bits de précision.
On peut augmenter la précision en utilisant une représentation sur 64 bits, mais il faut avoir
conscience que le calcul utilisant les nombres réel est un calcul approché dont la précision
dépend du nombre de bits disponible pour représenter votre information.
Ainsi, si vous voulez travailler sur des nombres réels ayant une écriture décimale nie, nous
vous encourageons à travailler en précision xée en utilisant des entiers.
Par exemple, 7, 34 peut très bien être vu comme l'entier 734 divisé par 100. Si vous voulez faire
2
l'opération 7, 34 , vous obtiendrez une valeur approchée du résultat : 53, 875602 alors que si
2
vous faites l'opération 734 vous obtiendrez le résultat exact : 538756. Il vous sut alors de lire
2 2 2
correctement les chires du résultat sachant que 7, 34 = (734/100) = 734 /10000 c'est à dire
de décaler la virgule de 4 positions vers la gauche, pour obtenir le résultat exact : 53, 8756.
Base 10 0 1 2 3 4 5 6 7 8 9
Binaire 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001
Exemple 15. En BCD, 345 est représenté par 0011 0100 0101
Ce codage est pratique dans les systèmes ne comportant pas d'unité de calcul est destiné seule-
ment à acher des nombres pour des utilisateurs humains, par le biais d'acheur 7 segments
par exemple.
Attention, la taille d'un int dépend du système à processeur utilisé (notamment de la taille du
mot machine que peut traiter le processeur) et donc de l'interprétation que donne le compilateur
associé au système lorsqu'il rencontre un int.
A titre d'exemple, on peut donner une table plus précise pour un processeur 32 bits.
Dans cette partie, nous décrivons l'architecture générale d'un système à microprocesseur et les
principes généraux de fonctionnement.
Précisons ici qu'un (micro)processeur ne peut pas fonctionner en étant isolé ce qui justie
l'appellation de systèmes à microprocesseur. Il est donc en interaction avec d'autres composants.
L'objectif de ce chapitre est de dénir quelles sont ces unités, de préciser leur rôle ainsi que les
interactions entre ces unités et le processeur.
Les deux composants principaux d'un système à microprocesseur sont la mémoire principale et
le processeur avec chacun des rôles bien dénis :
25
26 CHAPITRE 4. DESCRIPTION GÉNÉRALE PRINCIPES DE FONCTIONNEMENT
Par exemple, dans le cas d'une interaction homme-machine, un ordinateur aura l'architecture
générale présentée sur la gure 4.2.
Un processeur est entouré (ne voit que) de cases mémoires. Chaque case est accessible grace à
une adresse donnée. Pour communiquer avec une case mémoire, le processeur doit donc indiquer
son adresse. Puis, le processeur peut soit lire le contenu de la case, soit écrire dans une case.
Dans les deux cas, une donnée doit transiter entre le processeur et la mémoire.
Il y a trois types diérents d'information que s'échangent le processeur et la mémoire :
Une adresse ;
Un signal de contrôle (lire/ecrire dans l'exemple) ;
Une donnée.
Ces types d'information transitent par l'intermédiaire de ls d'interconnexion, chaque l permet
de transporter un bit d'information. Pour transporter plusieurs bits d'information simultané-
ment, il est nécessaire de grouper les ls, on parle alors de bus de communication qui permettent
aux diérents composants d'un système à microprocesseur de communiquer.
On distinguera donc :
4.2. TECHNOLOGIES DE FABRICATION DES CIRCUITS INTÉGRÉS 27
Un bus d'adresse ;
Un bus de contrôle (ou bus de commande) ;
Un bus de données.
Les largeurs et les signications précises de ces bus seront vues ultérieurement.
Par ailleurs, un circuit CMOS ne consomme signicativement du courant que lors des commu-
tations des transistors. Cette propriété a été à l'origine de circuits qui consomment moins de
courant que leur équivalent TTL, qui eux en consomment au repos et lors des commutations.
Néanmoins, au fur et à mesure qu'on diminue leur tension d'alimentation, les courants de fuite
des transistors CMOS deviennent de plus en plus proches des courants de commutation, et par
conséquent la consommation de ces circuits au repos n'est plus aussi négligeable qu'auparavant.
Le rôle du processeur est d'exécuter un ou des programmes. Un programme est une séquence
d'instructions placées en mémoire.
En général (selon le modèle de Von Neumann), pour réaliser une instruction un processeur suit
4 étapes :
4.4.3 En résumé
Un programme informatique (tel que vous pouvez l'écrire en C) est une suite d'instructions
de haut niveau, qui peuvent être très variées. Il est illusoire de penser qu'un processeur peut
éxecuter tous ces types d'instructions.
Un processeur possède un certain nombre d'instructions de base qui constituent son jeu d'ins-
tructions. Ces instructions de base sont par exemple :
addition de deux mots machine ;
lecture/écriture d'une case mémoire ;
ou logique entre deux mots machine ;
etc, . . .le jeu d'instruction d'un processeur est en général décrit précisément dans sa docu-
mentation.
A partir de ce jeu d'instructions, le processeur est capable (en séquençant les instructions de
base) de traiter des instructions plus complexes qui peuvent composer un programme.
Les instructions du jeu d'instructions du processeur sont codiées selon un langage très précis
appelé le langage machine. Le langage machine dépend du processeur.
Pour écrire un programme en langage machine, il faut donc connaître les détails du fonction-
nement du processeur qui va être utilisé.
Remarque 13. Le langage machine est un langage de très bas niveau qui ne travaille qu'avec des
adresses mémoires. Par exemple, le programme écrit en langage machine pour une architecture
80x86 par la séquence
A1 01
|{z} | {z10} 03
| {z06} 01
| {z12} |{z} | {z14} implantée en mémoire additionne le contenu de deux
A3 01
op. lecture adr op. add adr op. écriture adr
random indique que ces lectures-écritures peuvent se faire à des suites d'adresses totalement
quelconques, par opposition à des mémoires de type séquentiel (comme les disques durs) qui font
des séries d'accès à des adresses consécutives. Les ROMs (Read Only Memory) sont fonction-
nellement identiques aux RAMs, mais ne permettent que la lecture et pas l'écriture. Utilisées
dans la mémoire centrale d'un ordinateur, les RAMs pourront stocker les programmes et les
données, alors que les ROMs vont seulement stocker des programmes invariables, comme par
exemple le programme exécuté au démarrage de la machine, et stocké dans la ROM dite de
BIOS. Dans certains ordinateurs plus anciens, tout le système d'exploitation était stocké en
ROM, ce qui permettait d'avoir un système incorruptible et au démarrage rapide.
Une RAM peut être statique ou dynamique. Chaque bit mémoire d'une RAM statique (SRAM)
est constitué d'une bascule, et conserve son état tant qu'elle est alimentée. A l'inverse, chaque
bit d'une RAM dynamique (DRAM) est composé d'une capacité, qui doit être rafraîchie pé-
riodiquement par une électronique séparée. Les RAMs statiques ont un taux d'intégration plus
faible que les RAM dynamiques, puisqu'un bit mémoire nécessite 6 transistors dans un cas,
et une capacité plus un transistor dans l'autre. Une RAM peut être synchrone ou asynchrone,
une RAM synchrone étant en fait une RAM asynchrone à laquelle on a ajouté une machine à
états nis synchrone qui place les commandes de lecture et d'écriture dans un pipeline, an de
permettre d'accepter une nouvelle commande avant que la précédente n'ait été complétée.
Les barrettes de RAM de nos ordinateurs personnels sont des SDRAM, c'est à dire des RAM
dynamiques synchrones, fonctionnant à des fréquences de 200MHz et plus. Elles sont souvent
de type DDR (double data rate), quand les fronts montants et descendants de l'horloge sont
exploités pour les changements d'état. Dans beaucoup d'autres appareils (assistants person-
nels, consoles de jeux, etc.), la RAM est de type statique asynchrone (SRAM), sous la forme de
circuits intégrés. Les ROMs existent également dans un grand nombre de types diérents, prin-
cipalement selon la façon dont on peut programmer leur contenu (invariable, par dénition). Il
y a d'abord les ROMs programmées par masque à l'usine ; elles sont produites en grand nombre
avec un faible coût à l'unité, mais leur contenu ne peut jamais être mis à jour ultérieurement.
2. Compilation de votre code pour le rendre intelligible par le processeur ciblé. Le code est
ainsi transformé en une suite d'instructions élémentaires faisant partie du jeu d'instruction
du processeur ciblé ;
3. Le processeur :
4. le résultat de votre programme en mémoire peut alors être utilisé comme entrée d'un
autre programme, ou comme sortie utilisable par un périphérique de sortie (acheur 7
segments, actionneur, écran, etc...).
Chapitre 5
Espace adressable - Mémoires
Un processeur ne voit que des cases mémoires qui lui permettent de stocker de l'informa-
tion binaire et de communiquer avec les périphériques composant le système. Cet ensemble
de cases mémoires constitue l'espace adressable du processeur. Cependant, il faut distinguer
dans l'espace adressable du processeur, la partie dédiée au stockage de l'information (données
et programmes) et la partie correspondant aux périphériques du système. Enn, il convient de
préciser quelles sont les diérents types de mémoires, leurs capacités ainsi que les diérentes
technologies permettant de stocker l'information.
Remarque 15. Pour s'adresser aux périphériques du système, le processeur doit connaître
leur adresse. On peut donc voir les périphériques d'un système comme des parties de l'espace
adressable que voit le processeur.
Pour éviter toute confusion par la suite, on emploiera donc le terme d'espace adressable pour
indiquer le nombre de cases que voit le processeur et de mémoire la partie de l'espace adressable
réservée au stockage de l'information.
Mémoire centrale
Cette partie de la mémoire est la mémoire interne ou encore appelée mémoire vive ou encore
mémoire RAM (Random Access Memory). Elle permet de stocker temporairement des données,
notamment lors de l'exécution de programmes. C'est une mémoire volatile au sens où lorsqu'elle
n'est plus alimentée par un courant électrique, elle perd sa capacité de mémorisation.
L'accès à cette mémoire est rapide (quelques dizaines de nanosecondes) ce qui est important
pour ne pas ralentir la cadence à laquelle le processeur peut travailler.
33
34 CHAPITRE 5. ESPACE ADRESSABLE - MÉMOIRES
Remarque 16. La mémoire accessible dans le processeur, (registres voire mémoire cache), a
un temps d'accès encore plus court (quelques nanosecondes).
Mémoire de masse
Cette partie de la mémoire, appelée mémoire physique ou encore ROM (Read Only Memory)
permet de stocker des données sur le plus long terme, même lorsque le courant électrique est
coupé. C'est le cas des CD-ROM, DVD-ROM, mais aussi les disques durs et autres clés USB.
Les temps d'accès à ce type de mémoire sont beaucoup plus lents (quelques millisecondes),
aussi pour travailler sur des données présentes en mémoire de masse, le processeur va d'abord
les récupérer dans la mémoire centrale qui ore des temps d'accès beaucoup plus rapide.
Remarque 17. L'appellation mémoire à lecture seule (ROM) est conservée pour des raisons
historiques, cependant la plupart des périphériques de stockage de masse actuels (tels que les
disques durs, les clés USB utilisant la technologie FLASH) sont accessibles en lecture ET écri-
ture. Cependant les temps d'accès à ces mémoires sont beaucoup plus lent que pour des accès à
la RAM.
une case mémoire pourra contenir un multiple de 8 bits (=1 octet) d'information.
Si une case mémoire peut stocker 𝑚 bits d'information, on dit que la mémoire a une largeur de
𝑚 bits.
Adresse Emplacement
𝑛
2 −1 0 1 0 1 1 0 1 0
2𝑛 − 2
... ...
2
1
0
7 6 5 4 3 2 1 0
numéros des bits
Exemple 16. Un processeur a un bus d'adresse d'une largeur de 16 bits et un bus de donnée
d'une largeur de 8 bits. Calculez la capacité adressable du processeur. Schématiser les connec-
tions entre le processeur et son espace adressable dans ce cas.
Il convient de retenir que plus on s'éloigne du processeur, plus l'espace de stockage est important
mais plus les temps d'accès sont longs.
A l'inverse, plus on s'approche du processeur plus les capacités de mémorisation sont réduites
1
mais plus leur temps d'accès est rapide. Ceci est schématisé dans la gure 5.2 .
Cette notion de hiérarchie est importante pour ne pas ralentir le système. En eet, on distingue :
L'information sur laquelle est en train de travailler le processeur (stockée dans des registres
processeurs, stockage et durée de vie limités mais temps d'accès très rapide (quelques ns)) ;
L'information sur laquelle le processeur va travailler (stockée dans la mémoire centrale, sto-
ckage et durée de vie plus importants mais temps d'accès plus lent (quelques dizaines de
ns)) ;
L'information que le processeur est amenée à consulter de temps en temps (stockée dans de
la mémoire de masse (mémoire ash principalement en système embarqué), stockage et durée
de vie beaucoup plus important mais temps d'accès très lents (quelques ms)).
5.5 Technologies
L'objectif de cette partie est de comprendre comment peut être mémorisée l'information binaire
et d'étudier les technologies employées couramment pour mémoriser l'information.
Un des inconvénients majeurs de ce système est dû au fait que les condensateurs se déchargent
naturellement, il faut donc régulièrement (de l'ordre de quelques ms) rafraichir leurs états (c'est
à dire venir lire leur valeur et les recharger). Ce temps s'ajoute au temps d'accès à la mémoire
(temps de latence).
Cette technologie est simple à mettre en place ce qui ore l'avantage d'être peu onéreuse et
d'occuper une surface matérielle 4 fois moins importante que les RAM statiques (SRAM).
Pour plus de détails sur les diérentes technologies de RAM dynamique, le lecteur curieux
pourra consulter : http://www.commentcamarche.net/contents/pc/ram.php3.
2. http ://www.commentcamarche.net/contents/pc/ram.php3
38 CHAPITRE 5. ESPACE ADRESSABLE - MÉMOIRES
d'information existants, il n'est pas nécessaire de lire toutes les données situées devant celle que
l'on cherche avant de pouvoir accéder à l'information désirée.
Principe La cellule de base d'une RAM est typiquement constituée par une bascule
3
:
Exemple La matrice de cellules est intégrée dans un ensemble de circuits servant à sélection-
ner correctement les lignes et les colonnes :
Fonctionnement Le bus d'adresse A1A0 pilote un décodeur qui fournit les lignes de sélection
des cellules. La même ligne sert pour l'écriture et la lecture.
L'utilisation d'un même l pour sélectionner les cellules pour l'écriture d'une part, et pour la
lecture d'autre part, nécessite une ligne pour indiquer quelle est l'opération désirée : R/WR-
est à 0 lors d'une écriture, et à 1 lors d'une lecture. Ceci impose de modier le schéma de la
cellule de la façon suivante :
Mémoires statiques
La réalisation de ces mémoires est eectuée à l'aide d'un tableau de bascules (typiquement les
bascules RS vues en ENSL1, voir gure 5.8).
¯
𝑅 𝑆¯ 𝑄 ¯
𝑄
0 0 1 1
0 1 0 1
1 0 1 0
1 1 𝑄0 𝑄¯0
40 CHAPITRE 5. ESPACE ADRESSABLE - MÉMOIRES
Les ROMs
Principe Les mémoires ROMs (Read Only Memory) sont par dénition des mémoires en
lecture seule. Leur contenu a été déni une fois pour toute et elles ne sont plus inscriptibles
(voir par exemple gure 5.9).
adresse 𝑆4 𝑆3 𝑆2 𝑆1 𝑆0
11 01101
10 10111
01 10111
00 11110
Remarque Les liaisons entre les lignes de sélection d'adresse (lignes horizontales de la ma-
trice), et les lignes de données (lignes verticales de la matrice) ne peuvent être de simples
connexions, mais doivent être réalisées à l'aide de diodes. Les diodes servent à éviter un retour
de courant depuis la ligne sélectionnée vers une autre qui ne l'est pas (court-circuit) :
Réalisation pratique Les connexions entre les lignes et les colonnes peuvent par exemple
être réalisées à l'aide de transistors MOS dont on intègre ou non la grille au moment de la
fabrication de la puce :
ROM (Read Only Memory) : programmées en usine, ne peuvent pas être reprogrammées ;
PROM (Programmable Read Only Memory) : programmable une seule fois par l'utilisateur,
ne peuvent pas être reprogrammées par la suite. Les PROMs sont des mémoires non volatiles,
dont le contenu comme dans le cas des ROMs, est déni une fois pour toutes. Toutefois,
contrairement aux ROMs, elles sont programmables (1 seule fois), par l'utilisateur. Il existe
diérents types de PROMs. Les noeuds de la matrice peuvent comprendre soit des fusibles
soit des jonctions ayant une faible tension de claquage. Dans les deux cas, la programmation
s'eectue en sélectionnant l'adresse désirée, en présentatnt la donnée sur les lignes de sortie, et
en alimentant pendant un bref instant (quelques centaines de ms) le circuit avec une tension
élevée (10 à 15 V suivant les cas), ce qui a pour eet de faire fondre le fusible (ouverture
du circuit) ou de claquer la jonction (fermeture du circuit). Ce processus est évidemment
irréversible.
EPROM (Erasable Programmable Read Only Memory) : également appelées UV-PROM,
elles sont programmables par l'utilisateur et eaçables par eet photo-électrique à l'aide
d'UV captés par une fenêtre située au dessus du boîtier mémoire. Elles sont programmables
par octets, mais eaçable en globalité.
Le processus est réversible en irradiant la puce aux rayons ultraviolets pendant plusieurs
minutes, ce qui décharge la grille par eet photoélectrique.
Les EPROMs sont des mémoires non volatiles programmables puis eaçables par l'utilisateur.
Dans ce cas les noeuds de la matrice sont constitués de transistors MOS à grille isolée. Cette
grille peut être chargée par inuence en appliquant une tension importante (10 à 15 V) entre
le drain et le substrat. Une fois chargée, elle peut conserver sa charge de manière quasiment
indénie, ce qui rend le transistor passant.
EEPROM (Electricaly Erasable Programmable Read Only Memory) : elle peut être eacée
électriquement (plus pratique que les EPROM) et reprogrammée (octet par octet). Le nombre
de reprogrammations est limité (de 100000 à 1000000 de fois) mais la plupart du temps
susant.
Flash EPROM (Flash Erasable Programmable Read Only Memory) : La mémoire ash ore
les avantages d'une RAM et d'une ROM, c'est à dire qu'elle est non volatile et qu'elle est
accessible en lecture mais aussi en écriture et ore un temps d'accès plus rapide qu'une ROM,
mais plus lent qu'une RAM tout en ayant une consommation faible.
Elle est idéale pour de nombreuses applications embarquées (appareil photos numériques,
téléphonie, mini PC, lecteurs MP3, clés USB,. . .). Plus de 50% des mémoires volatiles sont
des mémoires ash.
Elle est programmable et eaçable électriquement comme les EEPROM (mais par secteur
entier et pas seulement par octets), elle ore cependant un meilleur compromis vitesse d'ac-
cès/capacité.
Les associations mémoires (série pour augmenter la largeur mémoire et parallèle pour augmenter
la capacité mémoire) seront étudiées au cours d'un TD sur les associations mémoires.
5.7. CAS PARTICULIERS 43
L'ordre d'empilement est l'inverse de l'ordre de dépilement. Ainsi le dernier entré est le premier
sorti, on parle de pile LIFO (Last In First Out).
En langage symbolique, on trouve deux instructions permettant de gérer la pile système :
PUSH registre : met le contenu du registre au sommet de la pile ;
POP registre : retire la valeur en haut de la pile pour la mettre dans un registre.
La pile est souvent utilisée pour sauvegarder temporairement le contenu des registres.
Exercice 1. Le microcontrôleur C167 d'Innéon possède un espace adressable de 16Mio qui est
segmenté et paginé.
1. Donner la taille de son bus d'adresse ;
2. La mémoire est organisée en 256 segments de taille identique. Trouver la taille de ces
segments ;
3. Sachant que les pages ont une taille xe de 16 Kio, trouver le nombre de pages par segment.
Remarque 18. La pagination et la segmentation de la mémoire sont intéressantes pour tra-
vailler avec des modes d'adressage logiques (Segment 1, page 6, oset 37) plus simples à gérer
que les adresses physiques (représentées en hexadécimal : 0x18025).
44 CHAPITRE 5. ESPACE ADRESSABLE - MÉMOIRES
5.8 En pratique
Les barrettes mémoires
Il existe de nombreux types de mémoires vives. Celles-ci se présentent toutes sous la forme
de barrettes de mémoire enchables sur la carte mère. Les premières mémoires se présentaient
sous la forme de puces appelées DIP (Dual Inline Package). Désormais les mémoires se trouvent
généralement sous la forme de barrettes, c'est-à-dire des cartes enchables dans des connecteurs
prévus à cet eet. On distingue deux types de barrettes de RAM :
les barrettes au format SIMM (Single Inline Memory Module) : il s'agit de circuits imprimés
dont une des faces possède des puces de mémoire. Il existe deux types de barrettes SIMM,
selon le nombre de connecteurs :
Les barrettes SIMM à 30 connecteurs (dont les dimensions sont 89x13mm) sont des mémoires
8 bits qui équipaient les premières générations de PC (286, 386).
emplacements mémoire (les bancs). Si vous avez deux détrompeurs, il s'agit soit de SDRAM
soit de RAMBUS. La RAMBUS à ses deux détrompeurs très rapprochés (voir ici), alors que la
SDRAM (voir ici) en à deux mais éloignés. La SDRAM-DDR (voir ici) n'a qu'un détrompeur
situé presque au milieu des bancs.
Identiez aussi la barrette : des informations peuvent être inscrites sur une étiquette collée
dessus. Dans le cas contraire, On peut aussi se er à la hauteur des chips : les chips sont
très peu épais, environ 1 mm (c'est de la mémoire récente : SDRAM, SDRAM-DDR,
SDRAM-DDR2, DR-RAM, etc.), si les chips sont assez épais, plus de 2 mm (c'est de la SIMM,
SIMM-EDO, etc.). On peut aussi compter le nombre de broches : 30 (c'est de la SIMM-30),
72 (c'est de la SIMM-72 ou SIMM-EDO), 168 (c'est de la SDRAM), 184 (c'est de la SDRAM-
DDR, SDRAM-DR2, DR-SDRAM), 240 (c'est de la SDRAM-DDR2). Enn, pour savoir si
votre barrette est une DIMM, SO-DIMM et Micro DIMM, il sut de mesurer la longueur de
la barrette. Avec 133 mm, votre barrette sera une DIMM. 67 mm pour une SO-DIMM 144
broches, 39 mm pour la Micro DIMM 144 broches et 44 mm pour la Micro DIMM 172 broches
(note : les mesures sont arrondies au mm le plus proche).
Les fabricants d'ordinateurs vendent souvent plusieurs gammes de produits, organisées en ser-
veurs et en stations de travail. Les serveurs vont contenir de la mémoire ECC dans leur archi-
tecture. Les fabricants de stations de travail Unix utilisent de la mémoire à parité et maintenant
ECC depuis plusieurs années dans toutes leurs gammes de produits. Cette dernière ore aussi
théoriquement un moyen de détecter des modications semi-aléatoires causées par certains
rayonnements (rayonnements alpha). Utiliser de la mémoire ECC sur un ordinateur dont le
contrôleur ne le gère pas, est une aberration. Prenez donc une mémoire NON-ECC qui sera
moins chère et tout aussi ecace dans votre cas.
46 CHAPITRE 5. ESPACE ADRESSABLE - MÉMOIRES
Chapitre 6
Architecture des (micro)processeurs
Dans ce chapitre, nous décrivons précisément l'architecture des processeurs et précisons le rôle
de leurs principaux constituants.
Cette description étant faite en toute généralité, elle ne décrit pas l'architecture d'un processeur
particulier mais les constituants de base de tout processeur. Pour connaître l'architecture précise
d'un processeur particulier, il n'y a pas d'autre solution que de se référer à son manuel.
On rappelle que le rôle d'un processeur est d'exécuter des programmes. Un programme est une
suite d'instructions élémentaires stockées en mémoire. Le processeur exécute donc séquentielle-
ment ces instructions.
6.1.1 L'horloge
Son rôle est de cadencer le microprocesseur. C'est le métronome du système permettant de
synchroniser les communications avec les autres éléments du système telle que la mémoire.
L'horloge peut être générée à l'aide d'un oscillateur à quartz (cristal à quartz souvent repéré
par son nom anglais XTAL) ou par l'utilisation d'une PLL (Phased Lock Loop) qui produit
des multiples de la fréquence d'oscillation du quartz.
Exemple 17. C'est le cas dans le C167 d'Inneon (Siemens). Un multiplexeur permet de
choisir si on veut utiliser la fréquence du quartz ou un de ses multiples.
Le signal produit est un signal créneau dont chaque front montant correspond à des tops
d'horloge.
Plus la vitesse de l'horloge est élevée, plus le 𝜇𝑃 peut exécuter les instructions de base à
un rythme élevé. La contre-partie est que cela génère des transitions plus fréquemment au
niveau des transitors et donc une consommation de courant plus importante ce qui implique un
échauement du circuit d'où la nécessité d'avoir une solution de refroidissement du processeur
adaptée.
47
48 CHAPITRE 6. ARCHITECTURE DES (MICRO)PROCESSEURS
Pour savoir à quel endroit de la mémoire regarder, le processeur utilise des adresses mémoires
pour repérer les cases contenant les instructions et les données du programme.
Les adresses circulent sur un bus de communication appelé bus d'adresse. Une adresse ne circule
que du processeur vers la mémoire. Le bus d'adresse est donc un bus unidirectionnel.
Une fois l'adresse choisie, une donnée (instruction ou donnée du programme) transite entre le
processeur et la mémoire.
Ces données transitent sur un bus de communication appelé bus de donnée. Une donnée peut
aller du processeur vers la mémoire (écriture) ou de la mémoire vers le processeur (lecture). Le
bus de donnée est donc bidirectionnel.
Parmis les registres les plus importants (qu'on retrouve dans la plupart des architectures à
microprocesseurs), on distingue :
1. les registres tampons : ils sont à l'interface entre le processeur et la mémoire et permettent
de stocker temporairement les communications mémoire/processeur. Comme la mémoire
et le processeur s'échangent deux principaux types d'information (adresses et données),
on distinguera :
les registres tampons d'adresse ;
les registres tampons de données ;
2. les registres de travail : stockent les diérentes données en cours de traitement par le
processeur. Leur nombre est variable et ils possèdent chacun leur nom propre qui permet
au programmeur de les manipuler en langage machine. On distingue :
Exemple 18. Supposons que l'instruction présente dans le registre (RI) soit décodée en une
instruction d'addition, le rôle de l'unité de contrôle est d'acheminer les deux opérandes dans
les registres adéquats de l'unité arithmétique et logique, puis d'ordonner à celle-ci de réaliser
l'opération d'addition, puis de récupérer le résultat du calcul pour le placer dans un registre
approprié. Et enn d'indiquer qu'il faut traiter l'instruction suivante (mise à jour du registre
IP).
L'unité de contrôle génère également tous les signaux de synchronisation internes ou externes
(bus de commandes ou bus de contrôle) au microprocesseur.
Instructions de comparaison
Comparaison du registre ACC à une donnée et positionnement des indicateurs d'état.
Exemple 20. L'opération 𝐴𝐶𝐶 −𝑑𝑜𝑛𝑛𝑒𝑒 est calculée, le résultat est perdu mais le bit indicateur
d'état 𝑁 est mis à 1 dans le registre d'état si 𝐴𝐶𝐶 < 𝑑𝑜𝑛𝑛𝑒𝑒.
Instructions de branchement
Ces instructions apparaissent lorsqu'il y a des boucles
(do{...}while(condition), while(condition){...}, . . .)
ou des tests
(if(condition){...} else {...}, . . .).
Dans ce cas, le processeur ne doit plus suivre l'ordre séquentiel des instructions placées en
mémoire mais doit eectuer des sauts (en avant ou en arrière). La prochaine instruction à
exécuter étant repérée en mémoire par le registre IP, c'est ce registre qui est modié lorsqu'un
saut doit être eectué.
On distingue deux types de branchements :
branchements inconditionnels : 𝐼𝑃 ← @𝑖𝑛𝑠𝑡𝑟𝑢𝑐𝑡𝑖𝑜𝑛 ;
branchements conditionnels : Si une condition est satisfaite, alors branchement, sinon passage
simple à l'instruction suivante.
champ champ
code opération code opérande
(1 ou 2 octets) (1 ou 2 octets)
Pour les processeurs possédant un jeu d'instructions réduit aux instructions les plus basiques,
on parlera de processeurs à architecture RISC (Reduced Instruction Set Computer, c'est à dire
calculateur à jeu d'instructions réduit). La plupart des processeurs génériques aujourd'hui sont
conçus selon cette architecture, notament pour son coût réduit et le fait que les instructions
basiques peuvent être exécutées en un cycle d'horloge.
6.3 Pipeline
Plus un processeur peut exécuter d'instructions rapidement plus il est performant. Nous avons
vu que la fréquence d'horloge utilisée était un des facteurs de performance du processeur. Ce
n'est pas le seul.
On rappelle que pour exécuter une instruction, le processeur suit 4 étapes principales :
1. fetch ;
2. decode ;
3. execute ;
4. writeback
Fetch 𝐼1 𝐼2
Decode 𝐼1 𝐼2
Execute 𝐼1 𝐼2
Writeback 𝐼1 𝐼2
−→ time
Dès qu'une étape d'une instruction est terminée, on eectue la même étape pour l'instruction
suivante :
Fetch 𝐼1 𝐼2 𝐼3 𝐼4 𝐼5
Decode 𝐼1 𝐼2 𝐼3 𝐼4 𝐼5
Execute 𝐼1 𝐼2 𝐼3 𝐼4 𝐼5
Writeback 𝐼1 𝐼2 𝐼3 𝐼4 𝐼5
−→ time
Cette seconde approche, appelée technique du pipeline, permet d'eectuer beaucoup plus d'ins-
tructions dans le même temps.
Attention, les instructions sont toujours exécutées séquentiellement mais à un instant donné,
plusieurs instructions sont traitées en même temps .
6.3. PIPELINE 53
Exemple 21. Par exemple au temps 4, 𝐼1 est en phase writeback, 𝐼2 en phase execute, 𝐼3
en phase decode et 𝐼4 en phase fetch. Aucune instruction n'est terminée, elles sont toutes en
cours de traitement (à des stades diérents) par le processeur.
Remarque 19. Notez que le pipeline n'est pas toujours possible, en particulier lorsqu'il y a une
dépendance entre deux instructions. Par exemple lorsque une instruction doit attendre le résultat
d'un long calcul (plusieurs cycles d'horloge) pour être exécutée, cela provoque des trous dans
le pipeline.
Ce n'est pas le cas le plus grave, lorsqu'il y a une interruption (logicielle ou matérielle, cf TP) il
faut purger le pipeline, c'est à dire sauvegarder le contexte des instructions en cours d'exécution.
Cette sauvegarde se fait en utilisant la pile et un pointeur de contexte pour se situer dans la
pile.
54 CHAPITRE 6. ARCHITECTURE DES (MICRO)PROCESSEURS
Chapitre 7
Les pointeurs
7.1 Présentation
Lorsque l'on déclare une variable, on réserve (on dit que l'on "alloue") une place en mémoire
(par exemple sur le disque dur) pour elle (plus ou moins grande suivant le type). Par exemple,
si on écrit int x ;, on peut représenter la mémoire comme ci-dessous :
Le numéro 1041 en face de la case x indique où est située la variable x dans la mémoire, en un
mot son "adresse". A chaque instant de l'exécution d'un programme, l'ordinateur sait où sont
situées les variables qui sont utilisées, il y a quelque part une structure (mettons, un tableau),
qui récapitule tout ça. Par exemple supposons que l'on a déclaré un caractère char y, on se
retrouve avec le schéma suivant :
Maintenant l'initialisation ne pose pas de problème, si on veut donner à y la valeur 'a', il sut
d'écrire y = 'a'; et l'ordinateur mettra le charactère 'a' dans l'adresse (la case) 1045. Idem
pour l'instruction x = 3; :
55
56 CHAPITRE 7. LES POINTEURS
On peut bien entendu récupérer l'adresse de x, avec &x. Cette adresse est notamment utilisée
pour stocker une valeur en la demandant à l'utilisateur : l'instruction scanf("%d",&x);, (x a
préalablement été déclarée, donc son adresse existe) va demander une valeur entière à l'utili-
sateur, et la stocker à l'adresse de x, c'est-à-dire à l'adresse 1041. L'ancienne valeur stockée à
cette adresse, si il y en avait une, est écrasée.
int main(void)
{
int x, char y;
x = 4;
y = 'z';
printf("%c",f(x,y));
return 0;
}
Lorsque l'on exécute la fonction main, on appelle la fonction f sur l'entier x, qui vaut 2 à ce
moment là, et le caractère y, qui vaut 'z' à ce moment là. La fonction f est donc appelée sur
les paramètres (2,'z'), et tout se passe comme si on avait directement fait appel à la fonction
de la façon suivante : f(2,'z').
En particulier, lorsque la fonction f est exécutée, on "invente" un paramètre a, qui est un entier
et qui vaut 2, et un paramètre c qui est un caractère et qui vaut 'z', on leur fait subir les
calculs à l'intérieur de la fonction f, ils sont utiles pour calculer la valeur de la fonction, mais
sont oubliés ensuite. En aucun cas la valeur 6 ne sera stockée quelque part lorsque la fonction
f aura ni de s'exécuter. NI DANS a, NI DANS x, CETTE VALEUR EST OUBLIéE.
Passage par adresse Quelquefois on aimerait bien pouvoir modier les paramètres d'une
fonction. Par exemple, comme on ne peut pas retourner deux entiers à la fois comme résultat
7.2. UTILISATION DES POINTEURS 57
d'une fonction, il peut être commode de pouvoir modier les paramètres entiers d'une fonction,
tout en enregistrant ces modications. Pour celà, on va utiliser les pointeurs :
int main(void)
{
int a,b;
a = 0;
b = 3;
g(&a,&b);
printf("%d %d",a,b);
return 0;
}
La fonction g ne prend plus en argument deux entiers, mais deux pointeurs sur les entiers,
autrement dit elle prend en argument deux "adresses de variables entières". int *pa désigne
la valeur entière pointée. Remarquez l'utilisation des étoiles.
Comment se déroule l'appel ? La fonction g ayant besoin de deux adresses, on lui donne les
adresses de a etb. La fonction g agit sur les contenus des cases d'adresses &a et &b, autrement
dit la fonction g a enregistré les modications faites sur les variables a et b. Le programme
imprime donc 1 4.
Ensuite, le programme principal appelle la procédure echange sur les adresses des variables a
et b, et donc celà échange les contenus des cases :
Le programme principal fait ensuite une impression à l'écran du contenu des variables a et b,
qu'il va chercher aux adresses qu'il connaît, donc il imprime : a = 10, b = 5.
Chapitre 8
Interruptions
En informatique, une interruption est un arrêt temporaire de l'exécution normale d'un pro-
gramme informatique par le microprocesseur an d'exécuter un autre programme (appelé rou-
tine d'interruption). Dans son acception la plus stricte, le terme ne désigne que des interruptions
dont l'exécution est provoquée par des causes externes au programme : avancement d'une hor-
loge, signalisation de la complétion d'un transfert de données, etc. Cependant, on l'utilise aussi
pour désigner des exceptions, c'est-à-dire des arrêts provoqués par une condition exceptionnelle
dans le programme (instruction erronée, accès à une zone mémoire inexistante, calcul arithmé-
tique incorrect, appel volontaire au système d'exploitation...). On parle alors parfois d'interrup-
tions asynchrones pour désigner celles provoquées par un événement externe, et d'interruptions
synchrones pour désigner les exceptions. Ces dernières étaient nommées déroutements en ter-
minologie CII-Honeywell-Bull.
8.1 Fonctionnement
Lors d'une interruption, le microprocesseur sauve tout ou partie de son état interne, géné-
ralement dans la pile système, et exécute ensuite une routine d'interruption, généralement en
suivant les directives d'une table indiquant pour chaque type d'interruption, le sous programme
à exécuter. Une fois le traitement de l'interruption terminé, la routine se nit normalement par
une instruction de retour d'interruption, qui restaure l'état sauvé et fait repartir le processeur
de l'endroit où il avait été interrompu. Dans certains cas, la routine d'interruption modie
les adresses de retour, notamment pour eectuer des commutations de tâches. Lors du fonc-
tionnement de certaines parties du système d'exploitation, il peut être nécessaire de ne pas
permettre les interruptions, soit parce que celles-ci perturberaient un compte serré du temps,
soit parce que des structures de données sont en cours de modication (on réalise ainsi une
sorte de verrou d'exclusion mutuelle dans un système mono-processeur). Aussi, on peut gé-
néralement bloquer (on dit souvent masquer) les interruptions. Dans la plupart des systèmes,
les interruptions bloquées sont accumulées, c'est-à-dire qu'elles sont exécutées dès qu'elles sont
démasquées. Cependant, pour chaque type d'interruption, le compteur d'interruptions en at-
tente se réduit souvent à un simple drapeau ; si cela peut ne pas être gênant si l'interruption
signale des données en attente sur un périphérique, cela peut cependant occasionner des mau-
vais comptes si l'interruption déclenche l'incrémentation d'une horloge, si les interruptions sont
bloquées pour une durée supérieure à la période de l'horloge. Sur certains systèmes, il existe une
interruption non masquable, généralement dédiée au signalement d'une erreur catastrophique
pour le système (par exemple, détection d'une erreur mémoire par code correcteur d'erreurs).
Les interruptions peuvent par ailleurs être hiérarchisées suivant des priorités. Une interruption
59
60 CHAPITRE 8. INTERRUPTIONS
de priorité supérieure est prise en compte lors du traitement d'une autre interruption, mais une
interruption de priorité inférieure est mise en attente.
8.2 Usages
On utilise les interruptions principalement dans deux buts : an de permettre des communica-
tions non bloquantes avec des périphériques externes ; an de commuter entre les tâches dans
un ordonnanceur. Un autre usage, celui-là non prévu initialement, est l'introduction de mal-
versations : lors de la restauration du contexte, si le contenu de la zone de sauvegarde a été
altéré depuis l'appel (c'est le cas si l'interruption ou le déroutement provoque en mode maître
une altération du contenu de la zone de sauvegarde ou de la pile), le contexte restauré sera
totalement diérent du contexte d'appel, et pourra passer la main à des suites d'instructions
hostiles. Les systèmes comme le matériel des microprocesseurs s'eorcent de plus en plus de
rendre ces tâches diciles pour les pirates, mais la faille - bien que fortement réduite aujourd'hui
- continue dans une certaine mesure à exister.
8.2.1 Entrées-sorties
Lorsque le microprocesseur interroge un périphérique (disque dur, port de communication...),
il y a en général des délais avant que les données ne puissent être obtenues ou transmises. La
solution la plus simple est simplement d'attendre les données ou la n de la transmission en
bouclant répétitivement sur un test (attente active, ou polling). Malheureusement, cela bloque
tout programme en cours, ce qui est gênant sur un système multi-tâche. Sur les systèmes
modernes, on préfère donc généralement un fonctionnement par interruption : le périphérique
signale par une interruption qu'il est prêt à émettre, ou que les données ont été transmises ou
reçues, et une routine fait le traitement nécessaire. Pour les périphériques rapides (disque dur,
USB...), on combine généralement ce procédé avec l'accès direct en mémoire (DMA) : des blocs
de données sont lus ou écrits en mémoire par le contrôleur sans intervention du processeur,
qui n'intervient qu'en début et en n de transfert. L'usage d'interruptions par rapport au
polling permet aussi des économies d'énergie et un moindre échauement : les microprocesseurs
actuels possèdent généralement une instruction arrêtant le microprocesseur en attente d'une
interruption.
8.2.2 Multi-tâche
On utilise également les interruptions pour commuter les tâches dans les systèmes multi-tâches.
Généralement, une interruption périodique est déclenchée par une horloge (souvent 100 ou 1
000 Hz), et l'ordonnanceur est alors mis en action. Il peut commuter les tâches en modiant la
tâche de retour de l'interruption.
8.3 Remarques
8.3.1 Priorité des interruptions
De façon tout à fait contre-intuitive, c'étaient dans les premiers systèmes les périphériques les
plus lents qui étaient aectés des priorités d'interruption les plus hautes. En eet : Ces inter-
ruptions étant peu nombreuses à cause de cette lenteur, leur haute priorité n'avait que peu
d'impact sur la charge Ces périphériques pouvaient être synchrones (interruption liée à une
8.4. CHIEN DE GARDE 61
colonne de carte perforée sous le lecteur, par exemple) et exiger un traitement aussi immédiat
que possible. Les priorités étaient attribuées en ordre décroissant ainsi : pupitre de commande,
lecteur de cartes, imprimante, disque. Les interfaces graphiques n'ont plus permis que le trai-
tement de l'écho d'un caractère soit traité par une routine de haute priorité (le positionnement
de cet écho, en multifenêtrage et avec des polices de taille variable, nécessite en eet plusieurs
dizaines de milliers d'opérations), et rendent paradoxalement ces interfaces bien moins réactives
dans les situations de forte charge machine, en dépit de l'usage de processeurs considérablement
plus puissants.
La plupart de ces ensembles spécialisés ne peuvent assurer seuls toutes les fonctions nécessaires
à leurs missions. Donc ils sollicitent parfois l'assistance du processeur principal, ne serait-ce que
pour fournir ou obtenir des informations issues d'autres éléments de la machine. Pour ce faire,
le processeur peut à intervalles réguliers interroger chacun d'eux an de déterminer s'il a besoin
d'aide, par exemple an de fournir ou bien d'obtenir des informations.
Ces interrogations répétées et souvent inutiles le distraient de sa mission qui consiste à animer
les programmes de l'utilisateur. De surcroît la fraction des ressources du processeur principal
constamment mobilisée par ces interrogations augmente avec le nombre et la puissance des
ensembles spécialisés.
Pour cela certaines pattes (contacts physiques) du processeur se trouvent reliées à des pistes
électriques le reliant aux ensembles spécialisés. Chacun de ces derniers peut s'y manifester en
modiant le niveau logique de la ligne an de requérir de l'aide, donc d'inviter le processeur à
prendre les dispositions nécessaires. Pour répondre à une requête le processeur devra :
Notes :
8.5. INTERRUPTION MATÉRIELLE 63
cette séquence d'événements peut survenir très fréquemment (plusieurs dizaines de milliers
de fois par seconde) ;
des composants auxiliaires (en particulier un circuit gestionnaire d'interruptions) assistent le
processeur lors de ces traitements ;
lorsque plusieurs interruptions surviennent simultanément, le processeur (voire le système
d'exploitation, lorsqu'il fournit la routine de gestion) dispose de moyens de déterminer leurs
priorités respectives donc l'ordre de prise en compte.
Les pistes électriques délivrant ces informations au CPU sont appelées lignes d'interruption ou
lignes d'IRQ. Dans un lointain passé chacune se trouvait associée, à un moment donné, à un
seul ensemble spécialisé mais des astuces permettent à présent de laisser plusieurs ensembles
solliciter le CPU par le biais de la même ligne d'IRQ, même de façon simultanée.
Le sigle IRQ désigne tout à la fois le concept même d'interruption de l'exécution sur requête
tierce ainsi que l'une de ces requêtes.