Le jeu d'instructions#
Nous avons toutes les pièces d'un processeur : des registres pour retenir, une mémoire pour ranger, une ALU pour calculer, un bus pour tout relier. Il nous manque une question : qu'est-ce qu'un programme, vu par le processeur ? La réponse tient en une phrase : une suite de nombres rangés dans la mémoire.
Notre processeur travaillera avec quatre registres de travail, r0, r1,
r2 et r3 : ce sont ses cases de calcul, ultra-rapides, sur lesquelles portent
la plupart des instructions.
Une instruction, c'est un nombre#
Un processeur ne comprend ni le français ni Python : il ne sait manipuler que des
nombres. Un programme, pour lui, est une suite de nombres rangés dans des
cases consécutives de la mémoire. Chacun est une instruction : un ordre
élémentaire, du genre "mets la valeur 13 dans r0" ou "ajoute r1 à r0".
Pour être lisible, une instruction est découpée en champs. Le premier, le code
opération (ou opcode), dit quoi faire. Les suivants désignent sur quels
registres agir. Comme il y a quatre registres, il faut 2 bits pour en nommer
un (00 = r0, 01 = r1, 10 = r2, 11 = r3). Sur nos 8 bits, on réserve
donc les 4 bits de gauche à l'opcode, puis 2 bits pour le registre de destination
Rd, et 2 bits pour le second registre Rs.
Une instruction se lit en trois morceaux : l'opcode (l'action), puis les deux registres concernés.#
Par convention, le premier registre est toujours la destination : c'est lui
qui reçoit le résultat. Ainsi ADD r0, r1 signifie "r0 reçoit r0 + r1". C'est
la même règle que dans les vrais assembleurs (x86, ARM).
Dans Logix, un composant SLICE fait exactement ce découpage : il extrait d'un mot un champ de bits choisi. Changez l'instruction ci-dessous et regardez ses trois champs apparaître.
Un petit jeu d'instructions#
La liste des instructions qu'un processeur sait exécuter s'appelle son jeu d'instructions. Voici le nôtre :
opcode |
instruction |
effet |
|---|---|---|
|
|
arrête le processeur |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
affiche le contenu de |
|
|
|
|
|
|
On retrouve nos composants : ADD, SUB, ET et OU font travailler l'ALU sur
deux registres (ce sont ses quatre opérations, vues au chapitre précédent), COPY
recopie un registre dans un autre, et LOAD fait entrer une valeur de l'extérieur.
Important
Un registre se nomme sur
2bits :r0 = 00,r1 = 01,r2 = 10,r3 = 11.Le premier registre d'une instruction est la destination (il reçoit le résultat).
ADD r0, r1fait doncr0 ← r0 + r1.
Une subtilité pour LOAD : la valeur à charger (par exemple 13) ne tient pas
dans les 4 bits qui restent. On l'écrit donc dans l'octet suivant : LOAD
occupe deux octets, l'instruction proprement dite, puis la valeur. C'est ainsi
que fonctionnent les vrais processeurs : certaines instructions sont plus longues
que d'autres.
Le cycle d'exécution#
Comment le processeur enchaîne-t-il les instructions ? Il répète sans fin un même
cycle en trois temps. Le program counter (pc) garde l'adresse de la
prochaine instruction.
Le processeur répète sans fin le même cycle : fetch, decode, execute (chercher, décoder, exécuter).#
Fetch (chercher) : lire dans la mémoire l'instruction à l'adresse indiquée par
pc, et faire avancerpc.Decode (décoder) : séparer l'opcode et les registres ; l'opcode détermine l'action.
Execute (exécuter) : réaliser l'action, en pilotant les composants concernés.
Pour une instruction LOAD, l'étape d'exécution va simplement lire l'octet
suivant (la valeur) et la ranger dans le registre, en faisant à nouveau avancer
pc.
Un programme complet#
Voici un programme rangé en mémoire à partir de l'adresse 0. Il met 13 dans
r0, 2 dans r1, les additionne dans r0, puis affiche le résultat.
adresse |
contenu binaire |
instruction |
|---|---|---|
|
|
|
|
|
(valeur : |
|
|
|
|
|
(valeur : |
|
|
|
|
|
|
|
|
|
En suivant le cycle, r0 prend la valeur 13, r1 prend 2, puis ADD r0, r1
met 13 + 2 = 15 dans r0, qui est affiché avant l'arrêt. Le processeur ne fait
pourtant jamais rien de compliqué : il répète chercher, décoder, exécuter.
Important
Un programme est une suite de nombres en mémoire ; chacun est une instruction faite d'un opcode et de registres.
Le processeur répète sans fin le cycle chercher, décoder, exécuter, en suivant le program counter.
Exercices#
Exercice 46#
Décodez chaque instruction : donnez son nom (menu déroulant) et le numéro des
registres visés (en décimal, de 0 à 3). Servez-vous du tableau du jeu
d'instructions.
0010 01 11: avec Rd = et Rs =0100 00 10: avec Rd = et Rs =0101 11 00: sur le registre0001 10 00: sur le registre
Exercice 47#
On exécute ce programme. Au départ, tous les registres valent 0.
adresse |
instruction |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Donnez le contenu des registres demandés à la fin, ainsi que la valeur affichée.
r0aprèsADD r0, r1:r2à la fin :r1à la fin :valeur affichée par
OUT r0:
Solution
LOAD r0, 5:r0 = 5.LOAD r1, 3:r1 = 3.COPY r2, r0:r2reçoit une copie der0, doncr2 = 5(etr0ne change pas).ADD r0, r1:r0reçoit5 + 3 = 8.OUT r0affiche donc8. À la fin :r0 = 8,r1 = 3,r2 = 5.
Exercice 48#
Écrivez, avec le jeu d'instructions du cours, un programme qui met 10 dans r0
et 4 dans r1, garde une copie de r0 dans r2, calcule r0 - r1 dans
r0, puis affiche d'abord r0 et ensuite r2.
Solution
LOAD r0, 10 r0 = 10
LOAD r1, 4 r1 = 4
COPY r2, r0 r2 = 10 (on garde l'ancienne valeur de r0)
SUB r0, r1 r0 = 10 - 4 = 6
OUT r0 affiche 6
OUT r2 affiche 10
STOP
La copie dans r2 est indispensable : SUB r0, r1 écrase r0, donc sans la
copie préalable on perdrait la valeur 10.
Exercice 49#
L'instruction ADD r0, r1 range son résultat dans r0, en écrasant l'ancien
contenu de r0. Un élève veut calculer r0 + r1 tout en gardant intactes les
valeurs de r0 et de r1. Expliquez comment y arriver avec les instructions du
cours.
Solution
On recopie d'abord r0 dans un registre libre, par exemple COPY r2, r0, puis on
fait l'addition dans cette copie : ADD r2, r1. À la fin, r2 contient r0 + r1,
tandis que r0 et r1 sont inchangés. C'est le rôle typique de COPY : préserver
une valeur avant une opération qui écraserait un registre.