Le même geste, des milliards de fois
Le serveur d’une boutique en ligne fait environ trois milliards de pas par seconde. Chacun de ces pas suit la même petite routine.
Prendre l’instruction suivante, comprendre ce qu’elle demande, le faire, puis passer à la suivante. Qui sait suivre cette routine pour une instruction peut la suivre pour n’importe quel programme.
À la fin de cette leçon
Remarque
Je peux suivre la recherche, le décodage et l’exécution d’une instruction.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Compteur ordinal | le registre qui contient l’adresse de la prochaine instruction | pc |
| Registre d’instruction | l’endroit où l’instruction qu’on vient de lire est gardée | |
| Recherche | la lecture de la prochaine instruction en mémoire | |
| Décodage | le découpage de l’instruction en champs | |
| Exécution | le travail que demande l’instruction | |
| Code opération | le champ qui dit de quelle sorte d’instruction il s’agit | opcode |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une routine qui recommence sans cesse
Le compteur ordinal, pc, contient l’adresse de la prochaine instruction. Pendant la recherche, le processeur lit le mot à cette adresse, le met dans le registre d’instruction et ajoute 4 à pc.
Pendant le décodage, il découpe le mot en champs : quelle sorte d’instruction, quels registres. Pendant l’exécution, il fait le travail et écrit le résultat. Puis il recommence la recherche.
Aller dans le dossier d’architecture
cd ~/archAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Assembler le add.s du labo
riscv64-linux-gnu-as add.s -o add.oAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Faire l’édition de liens
riscv64-linux-gnu-ld add.o -o addAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Voir l’émulateur lire et décoder
qemu-riscv64 -d in_asm ./addAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce que l’émulateur a lu
qemu a lu cinq mots en mémoire et a décodé chacun. Chaque ligne donne l’adresse, le mot en hexadécimal et l’instruction décodée.
Les adresses avancent de 4, de 0x000100b0 à 0x000100c0, car chaque instruction fait ici 4 octets. Remarquez que li a disparu : le processeur ne voit que addi a0,zero,2.
Le décodage découpe le mot en champs
Une instruction RISC-V fait 32 bits, coupés en champs. Les sept bits du bas sont le code opération : 19 veut dire un calcul avec un immédiat.
Viennent ensuite cinq bits pour rd, le registre de destination, puis trois bits de précision. Suivent cinq bits pour rs1, le registre d’entrée, et douze bits pour l’immédiat. a0 est x10. Ainsi 00200513 veut dire : x10 = x0 + 2.
Exemple travaillé : les champs de 00200513
| Bits | Champ | Valeur | Sens |
|---|---|---|---|
| 31 à 20 | imm | 000000000010 (2) | Le nombre à ajouter |
| 19 à 15 | rs1 | 00000 (0) | Entrée : x0, zero |
| 14 à 12 | funct3 | 000 | Une addition |
| 11 à 7 | rd | 01010 (10) | Le résultat va dans x10, a0 |
| 6 à 0 | opcode | 0010011 (19) | Calcul avec un immédiat |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
L’instruction en 32 bits
python3 -c "print(format(0x00200513, '032b'))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Extraire opcode, rd, rs1 et immédiat
python3 -c "print(0x00200513 & 127, (0x00200513 >> 7) & 31, (0x00200513 >> 15) & 31, 0x00200513 >> 20)"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
L’exécution, puis pc avance
L’exécution fait le travail : une addition, un chargement, une comparaison. La plupart des instructions laissent pc là où la recherche l’a mis, 4 plus loin. Un branchement pris écrit à la place une nouvelle adresse dans pc : un saut n’est rien d’autre.
Avec -d exec, qemu affiche une ligne par instruction exécutée. Le deuxième nombre entre crochets est le pc RISC-V.
Une ligne par instruction exécutée
qemu-riscv64 -one-insn-per-tb -d exec,nochain ./addAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Compter ces lignes
qemu-riscv64 -one-insn-per-tb -d exec,nochain ./add 2>&1 | wc -lAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Erreur fréquente
Attention
Beaucoup pensent que le compteur ordinal compte les instructions exécutées. Il ne compte rien. Il contient une adresse : celle de la prochaine instruction. Dans une boucle, il repasse par les mêmes adresses encore et encore.
Un pas sur le processeur de la machine
gdb peut arrêter un programme natif et exécuter une instruction à la fois. Tapé à la main, il attend vos ordres. Avec -batch et une liste d’ordres, il les exécute puis se termine : un bouton peut donc l’utiliser.
La commande s’arrête sur main, affiche pc, avance d’une instruction avec stepi et affiche de nouveau pc. Sur Arm, l’adresse avance de 4. Sur x86, une instruction fait de 1 à 15 octets, donc le pas varie.
Construire le programme loop du labo
gcc -O2 -o loop loop.cAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
S’arrêter sur main et avancer d’un pas
gdb -batch -iex 'set debuginfod enabled off' -ex 'break main' -ex run -ex 'info registers pc' -ex stepi -ex 'info registers pc' ./loopAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Pour aller plus loin : compter une boucle
Reconstruisez fois.s de la leçon sur les instructions. Avant de lancer quoi que ce soit, calculez combien d’instructions il exécute : deux avant la boucle, trois par tour, cinq tours, deux après.
Tapez ensuite qemu-riscv64 -one-insn-per-tb -d exec,nochain ./fois 2>&1 | wc -l et comparez. Quelle adresse apparaît cinq fois en tête de boucle ?