Registres, ALU, décodeurs… les pièces du moteur qui font tourner votre factorielle.
Un processeur moderne, c'est une usine à instructions. Ça arrive en flux, ça passe sur un tapis roulant, chaque atelier fait sa part du boulot, et à la fin une resultat sort — en principe celui que vous vouliez.
Entre tout ça : des kilomètres de transistors, des horloges qui tickent à plusieurs milliards de fois par seconde, et suffisamment de fils pour emballer la Terre.
Les registres sont les 16 petits casiers de la banane du processeur. Accès : 1 cycle horloge. Pas de « veuillez patienter ». Pas de « votre fichier est sur le disque réseau ». Juste boum, c'est là.
Notre code assembleur utilise une partie seulement. Voici les stars de la factorielle :
| Nom complet | Signification | Registres 32 bits | Registres 16 bits | Registres 8 bits |
|---|---|---|---|---|
%rax | Accumulator | %eax | %ax | %al / %ah |
%rbx | Base | %ebx | %bx | %bl / %bh |
%rcx | Counter | %ecx | %cx | %cl / %ch |
%rdx | Data | %edx | %dx | %dl / %dh |
Un registre spécial dont chaque bit raconte quelque chose sur la dernière opération :
| Flag | Bit | Signification | Exemple |
|---|---|---|---|
ZF | 6 | Zero Flag — résultat nul | cmp de deux valeurs égales → ZF=1 |
SF | 7 | Sign Flag — résultat négatif | cmp n,0 avec n négatif → SF=1 |
OF | 11 | Overflow Flag — débordement signé | 127+1 en 8 bits → 128, OF=1 |
CF | 0 | Carry Flag — retenue / emprunt | addition 64-bit qui dépasse → CF=1 |
PF | 2 | Parity Flag — nombre de bits à 1 pair | utile… pour les trucs qui datent du 8086 |
ALU = Arithmetic Logic Unit. C'est le cœur du réacteur. Elle additionne, soustrait, multiplie, divise, décale, fait du ET/OU/XOR, compare… et met à jour les flags.
Quand notre code fait imulq %rdx, %rax, c'est l'ALU qui tourne
— elle prend deux entrées (les registres), les balance dans son circuit de
multiplication, et écrit le résultat dans %rax.
# Chaque fois que vous voyez l'une de ces instructions, l'ALU sue : imulq %rdx, %rax ; multiplication → ALU en mode bourrin addl $1, -12(%rbp) ; addition → ALU en mode cantine salq $4, %rax ; décalage → ALU en mode déménageur cmpl %eax, %ebx ; comparaison → ALU en mode arbitre
| Composant | Rôle | Dit comme ça |
|---|---|---|
| ALU (U = Unit) | Opérations arithmétiques et logiques sur entiers | Le couteau suisse |
| FPU (F = Floating) | Opérations sur nombres flottants (float, double) | L'ALU qui a fait maths sup |
| AGU (A = Address) | Calcule les adresses mémoire (rbp-20, etc.) | Le GPS de bord |
| SIMD (SSE/AVX) | Une opération sur plusieurs données à la fois | Le rouleau compresseur |
%rbp - 20 pendant que l'ALU fait la multiplication.
C'est ce qu'on appelle du parallélisme au niveau instruction.
C'est aussi pourquoi votre processeur arrive à regarder YouTube
tout en compilant votre code :
il a plusieurs équipes de déménageurs.
Le processeur ne parle pas assembleur. Il parle microcode. Le décodeur est l'interprète attitré : il prend vos instruction x86-64 (qui peuvent faire de 1 à 15 octets — merci l'héritage CISC) et les traduit en une séquence d'opérations microscopiques (micro-ops) que le cœur exécute.
# Ce que vous écrivez : addl $1, -12(%rbp) # Ce que le décodeur comprend : * charger la valeur à l'adresse rbp-12 * ajouter 1 * écrire à l'adresse rbp-12 * mettre à jour les flags (ZF, SF, OF, CF) # Soit typiquement 2 à 3 micro-ops.
Une instruction ne passe pas d'un coup dans l'ALU. Elle traverse des étapes — comme dans une chaîne de montage automobile :
Chaque étape prend 1 cycle. Donc une instruction met 5 cycles à passer, mais on en délivre une par cycle. C'est comme une baguette de pain : elle met 12h à arriver, mais toutes les 30 secondes quelqu'un en achète une.
Aller chercher une valeur dans la RAM, ça prend environ 100 cycles. Le processeur déteste attendre. Alors il a construit un frigo (le cache) à côté de son bureau.
| Niveau | Taille typique | Latence | Localisation |
|---|---|---|---|
| L1 | 32 Ko (données) + 32 Ko (instructions) | ~4 cycles | Dans le cœur |
| L2 | 512 Ko | ~12 cycles | Dans le cœur (ou partagé) |
| L3 | 8–32 Mo | ~40 cycles | Partagé entre tous les cœurs |
| RAM | 8–64 Go | ~100 cycles | Sur la carte mère |
| SSD / Disque | — | ~10⁷ cycles | On a arrêté de compter |
L'unité de contrôle (Control Unit) est le chef d'orchestre. Elle ne calcule rien, elle décide qui fait quoi, quand, et dans quel ordre.
Elle lit le compteur ordinal (%rip), envoie l'adresse de l'instruction
au cache L1, ordonne au décodeur de traduire, dit à l'ALU de se réveiller,
dit au bus mémoire d'écrire le résultat… bref, c'est le chef de projet
qu'on n'a jamais vu coder mais sans qui rien ne sort.
Le bus relie tout ça : le processeur, la RAM, les périphériques. Il y a le bus d'adresse (pour dire où), le bus de données (pour dire quoi), et le bus de contrôle (pour dire comment).
# Quand notre code accède à la mémoire : movl -12(%rbp), %eax ; adresse → bus d'adresse ; donnée → bus de données ; lecture → bus de contrôle
Ça a l'air simple, mais c'est un protocole complexe avec des signaux d'acquittement, de priorité, et des arbitrages parce que oui, les cœurs se battent pour la RAM.
| Composant | Rôle | Traduction libre |
|---|---|---|
| TLB (Translation Lookaside Buffer) | Cache des traductions d'adresses virtuelles → physiques | L'annuaire téléphonique du MMU |
| MMU (Memory Management Unit) | Traduit les adresses virtuelles en adresses physiques | Le douanier qui vérifie les passeports |
| Branch Predictor | Devine si le saut conditionnel sera pris ou non | Madame Irma du processeur |
| ROB (ReOrder Buffer) | Permet l'exécution dans le désordre | La poste : on dépose, on réordonne, on livre |
| PMU (Performance Monitoring Unit) | Compte les événements (cache misses, branches mal prédites…) | La CAF du processeur |
| APIC (Advanced Programmable Interrupt Controller) | Gère les interruptions | Le réveille-matin des cœurs |
C'est tout bête. On prend une instruction, on la cuisine en cinq étapes, on dépose le résultat, et on recommence des milliards de fois par seconde. C'est ce qu'on appelle le cycle de von Neumann (1945). Ça n'a pas changé depuis. On a juste ajouté de la prédiction, du désordre, du cache, du multi-cœur… mais l'idée de base est toujours là.
| Terme | Définition express |
|---|---|
| CISC | x86-64 — instructions complexes, taille variable, héritage pléthorique |
| RISC | ARM, RISC-V — instructions simples et fixes, le zen du processeur |
| µop | Micro-opération — l'instruction une fois passée au décodeur |
| Pipeline | Chaîne de montage : Fetch → Decode → Execute → Memory → Writeback |
| Hazard | Quand une instruction doit attendre l'autre — data, control, structural |
| Forwarding | Court-circuiter le pipeline : « j'ai le résultat tout de suite, prends-le » |
| Branch misprediction | Le prédicteur a dit « saut pris » mais le saut n'a pas été pris. Tout le pipeline est vidé. |
| Speculative execution | Exécuter avant d'être sûr, au cas où. (Merci Meltdown/Spectre d'avoir gâché la fête.) |
| Out-of-Order | Exécuter dans le désordre pour ne pas perdre de cycles, puis reconstituer l'ordre logique |
| Hyper-Threading (SMT) | Un cœur physique qui fait semblant d'être deux (pour mieux utiliser le pipeline) |
man gcc et on espère.