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, des multiplexeurs pour aiguiller les données. 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 font travailler l'ALU sur deux
registres, 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 compteur ordinal (pc) garde l'adresse de la
prochaine instruction.
Le processeur répète sans fin le même cycle : chercher, décoder, exécuter.#
Chercher : lire dans la mémoire l'instruction à l'adresse indiquée par
pc, et faire avancerpc.Décoder : séparer l'opcode et les registres ; l'opcode détermine l'action.
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 compteur ordinal.
Exercices#
Exercice 45#
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 46#
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 47#
É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 48#
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.