Le compteur ordinal expliqué : le marque-page du processeur
Découvrez comment le compteur ordinal désigne la prochaine instruction, progresse dans le code séquentiel et est redirigé par les branchements, sauts, exceptions et réinitialisations.
En bref : le compteur ordinal, ou PC — également appelé pointeur d’instruction dans certaines architectures — désigne la prochaine instruction à charger. L’exécution séquentielle l’avance de la longueur décodée de l’instruction ; les branchements, sauts, exceptions, interruptions et réinitialisations sélectionnent une autre valeur pour le prochain PC.
Le compteur ordinal est un élément d’état architectural spécialisé, situé au cœur de la lecture des instructions. Dans un processeur pédagogique, il peut s’agir d’un registre littéral qui pilote l’adresse de la mémoire d’instructions. Dans un processeur moderne, prédiction, files d’attente, caches, traduction d’adresses et lecture spéculative rendent l’implémentation plus distribuée, mais l’architecture définit toujours l’adresse de la prochaine instruction.
Cet article explique ce que stocke le PC, comment il s’incrémente, comment les branchements et les sauts le redirigent, puis comment en câbler un à partir d’un registre, d’un additionneur et d’un multiplexeur. Chaque composant renvoie vers un circuit fonctionnel que vous pouvez manipuler dans le modèle Exécuteur séquentiel d’instructions.
Qu’est-ce que le compteur ordinal ?
Le compteur ordinal est un registre consacré à une seule tâche : pointer vers la prochaine instruction en mémoire. Ce n’est pas un registre général que le code utilisateur peut lire et écrire librement. C’est un registre spécialisé piloté par la logique de commande du processeur.
Dans la machine la plus simple, sa largeur et l’unité adressable de la mémoire délimitent l’espace des adresses de code :
- Un PC de 8 bits peut sélectionner emplacements adressables.
- Un PC de 16 bits peut sélectionner emplacements.
- Un PC de 32 bits possède motifs de bits possibles.
- Un PC de 64 bits possède motifs de bits possibles.
Ces emplacements ne sont des octets que dans une architecture adressée par octets. Les processeurs réels peuvent implémenter moins de bits d’adresse que la largeur nominale du registre, traduire les adresses virtuelles des instructions en mémoire physique et imposer des règles d’alignement ou d’adresses canoniques.
Le composant PROGRAM_COUNTER_8BIT de DigiSim réalise le cas de 8 bits : une taille suffisante pour exécuter de vrais programmes dans le simulateur, tout en restant assez petite pour être inspectée bit par bit.
Le PC se trouve en tête de l’étage de lecture
L’étage de lecture du cycle lecture-décodage-exécution utilise quatre signaux successivement :
- Le PC place sa valeur courante sur le bus d’adresses.
- La mémoire renvoie le mot d’instruction situé à cette adresse.
- Le mot d’instruction est verrouillé dans le registre d’instruction.
- Le PC est mis à jour afin que la lecture suivante obtienne l’instruction suivante.
Les étapes 1 à 3 sont traitées dans la présentation générale de la lecture. Le présent article porte sur l’étape 4.
Pourquoi le PC doit-il s’incrémenter automatiquement ?
Si le PC restait immobile, le processeur lirait éternellement la même instruction. Le matériel intègre donc un incrément automatique : par défaut, chaque cycle de lecture est suivi d’un pas en avant.
L’incrément est calculé par un additionneur dédié — généralement un petit additionneur à propagation de retenue semblable à celui détaillé dans Maîtriser l’addition binaire — dont les entrées sont le PC courant et un décalage constant. La sortie de cet additionneur revient vers l’entrée de données du PC, qui la verrouille au front d’horloge suivant.
PC + 1 ou PC + 4 : pourquoi la largeur de l’instruction compte
La constante ajoutée au PC est la largeur d’une instruction exprimée en unités adressables, et pas toujours la valeur littérale 1.
| Architecture | Largeur d’instruction | Incrément | Raison |
|---|---|---|---|
| Processeur pédagogique DigiSim de 8 bits | 1 octet (1 mot) | PC + 1 | Chaque adresse contient une instruction complète |
| MIPS ; RISC-V sans instructions compressées | 4 octets | PC + 4 | La mémoire est adressée par octets ; ces codages occupent 4 octets |
| ARM (A32) | 4 octets | PC + 4 | Même raison |
| RISC-V avec l’extension C ; Arm Thumb/Thumb-2 | 2 ou 4 octets | PC + longueur décodée | Tous deux comprennent des codages de 16 bits ; des codages de 32 bits peuvent aussi apparaître |
| x86 | 1 à 15 octets | PC + longueur décodée | Instructions de longueur variable ; le décodeur indique la longueur |
Le principe architectural reste identique : l’adresse séquentielle suivante dépend du codage de l’instruction courante. Une ISA à largeur fixe peut employer un incrément constant. Une ISA à largeur variable doit déterminer la longueur de l’instruction courante, même si un frontal hautes performances prédit et lit au-delà de cette frontière avant la fin du décodage.
Description booléenne
Pour une architecture dont la largeur fixe d’instruction est , la valeur suivante du PC par défaut est :
Dans le cas DigiSim de 8 bits, ; l’incrément est donc un simple additionneur +1.
Comment les branchements et les sauts remplacent-ils le PC ?
L’exécution séquentielle est le cas sans surprise. Un vrai programme a besoin de boucles, de conditions, d’appels de fonction et de retours : autant d’opérations qui imposent au PC de sauter ailleurs qu’à l’adresse séquentielle suivante.
Deux catégories courantes de transfert de contrôle illustrent ce changement :
- Saut inconditionnel : remplacer le PC par une adresse cible sans tenir compte d’une condition.
- Branchement conditionnel : sélectionner une cible uniquement si la condition définie par l’ISA est vraie ; sinon, choisir l’adresse séquentielle. Certaines ISA testent des indicateurs d’état tels que zéro, retenue, signe ou débordement. D’autres, dont le RISC-V de base, comparent directement des registres et ne possèdent aucun registre de codes conditionnels arithmétiques. Le guide des indicateurs du processeur explique l’organisation fondée sur ces indicateurs.
Dans les deux cas, l’opération revient à écrire une valeur non séquentielle dans le PC.
D’où vient l’adresse cible ?
La cible est codée de l’une des trois manières suivantes :
- Immédiate, relative au PC : le mot d’instruction contient un décalage. Le prochain PC vaut
PC + offset. Les instructionsBEQde RISC-V,Bd’ARM et les sauts courts de x86 emploient cette forme. Elle favorise le code indépendant de sa position. - Directe ou relative à une région : l’instruction fournit certains bits de la cible, éventuellement combinés avec une base fixe ou les bits de poids fort du PC courant. L’instruction
Jdu MIPS classique en est un exemple familier. Une adresse absolue complète tient rarement dans une instruction ordinaire de largeur fixe. - Indirecte par registre : la cible se trouve dans un registre général ou dans la sortie de l’ALU.
JALRde RISC-V,BXd’ARM etJMP raxde x86 en sont des exemples. Cette forme prend en charge les pointeurs de fonction, la répartition virtuelle et lesgotocalculés.
Dans un petit chemin de données monocycle, ces candidats peuvent alimenter un multiplexeur. Les implémentations plus avancées peuvent calculer, prédire et mettre en file les cibles dans plusieurs unités avant la validation du chemin architectural choisi.
Réalisation : registre + incrément + multiplexeur
La structure matérielle du PC est l’un des chemins de données les plus limpides d’un processeur :
┌──────────────┐
PC current ─────▶│ Adder (+W) │──── PC + W ──┐
└──────────────┘ │
▼
┌───────────────┐
│ MUX (2:1) │
target_addr ─────────────────▶│ sel = take? │──── next_PC
└───────────────┘
│
▼
┌───────────────┐
clock ─────────────────────▶│ PC register │──── current_PC
└───────────────┘
Trois éléments :
- Un registre qui conserve l’adresse courante. Dans le chemin de données pédagogique, il s’agit d’un registre de 8 bits, construit à partir d’un stockage déclenché sur front et élargi à la taille du bus d’adresses.
- Un additionneur dont une entrée reçoit le PC et l’autre la largeur constante .
- Un multiplexeur 2:1 dont une entrée vient de l’additionneur — chemin séquentiel par défaut — et l’autre de la cible de branchement — chemin du branchement pris. La ligne de sélection est pilotée par l’unité de commande et activée lorsque l’instruction courante est un saut ou un branchement dont la condition est vraie. Les multiplexeurs sont étudiés dans Le contrôleur du trafic de données.
À chaque front d’horloge, le PC verrouille la valeur que le multiplexeur sélectionne à cet instant. Cet unique verrouillage constitue tout le mécanisme qui distingue « avancer » de « brancher ».
Entrées facultatives du multiplexeur
Les conceptions réelles ajoutent d’autres sources au même multiplexeur :
| Source | Moment de la sélection |
|---|---|
| PC + W | Par défaut — exécution séquentielle |
| PC + décalage (relatif au PC) | Branchements conditionnels, sauts courts |
| Cible directe / vecteur | Sauts directs, réinitialisation ou transferts de contrôle définis par l’architecture |
| Registre / sortie d’ALU | Sauts indirects, retours de fonction, répartition de switch |
| Vecteur de réinitialisation / démarrage | Après la mise sous tension ou une réinitialisation externe |
| Vecteur d’exception / interruption | Après une trappe |
La ligne de sélection passe de 1 à 3 bits, mais l’idée structurelle reste la même.
Comportement à la réinitialisation : où commence le PC ?
À la mise sous tension ou lors d’une réinitialisation, le PC doit contenir une adresse connue ; sinon, l’exécution commence au hasard.
Deux conventions sont courantes :
- PC = 0 : l’exécution commence à l’adresse
0x0000…0. Le processeur pédagogique de DigiSim suit cette convention simple, avec la première instruction à l’emplacement zéro. - Vecteur de démarrage : une adresse fixe non nulle. À froid, x86 se réinitialise à l’adresse physique
0xFFFFFFF0, en haut de l’espace de 4 Go, près de la ROM du BIOS. Les cœurs ARM Cortex-M lisent le PC initial depuis un vecteur de réinitialisation stocké à l’adresse0x00000004. Certaines puces de la famille 6502 lisent ce vecteur à0xFFFC/0xFFFD.
Dans le matériel, « reset » est un fil relié à l’entrée d’effacement asynchrone — ou de chargement synchrone — du PC. Lorsqu’il est actif, le PC est forcé à la valeur de démarrage sans tenir compte du multiplexeur.
Exemple détaillé : une boucle de cinq instructions
Considérons le pseudo-programme suivant pour un processeur de 8 bits où :
0x00: LDI R0, 5 ; load 5 into R0
0x01: LDI R1, 0 ; load 0 into R1
0x02: ADD R1, R0 ; R1 = R1 + R0
0x03: DEC R0 ; R0 = R0 - 1, sets Z flag if R0 hits 0
0x04: BNZ 0x02 ; if Z == 0, branch back to 0x02
0x05: HLT
Suivons les valeurs du PC :
| Cycle | PC à la lecture | Instruction | Après la lecture | Branchement pris ? | PC suivant |
|---|---|---|---|---|---|
| 1 | 0x00 | LDI R0, 5 | PC + 1 = 0x01 | sans objet | 0x01 |
| 2 | 0x01 | LDI R1, 0 | PC + 1 = 0x02 | sans objet | 0x02 |
| 3 | 0x02 | ADD R1, R0 | PC + 1 = 0x03 | sans objet | 0x03 |
| 4 | 0x03 | DEC R0 (R0=4, Z=0) | PC + 1 = 0x04 | sans objet | 0x04 |
| 5 | 0x04 | BNZ 0x02 | PC + 1 = 0x05; target = 0x02 | oui (Z=0) | 0x02 |
| 6 | 0x02 | ADD R1, R0 | … | … | … |
Au cycle 5, le chemin de données pédagogique sélectionne la cible de branchement (0x02) à la place de l’adresse séquentielle suivante (0x05), car l’indicateur Z est effacé. La machinerie du flux de contrôle réel est plus élaborée, mais le résultat architectural reste le choix entre le chemin de poursuite et une cible de transfert de contrôle.
Pièges courants
- Erreur d’une unité dans PC + W. Un bogue de simulateur fréquent consiste à employer
PC + 1pour une architecture dont les instructions occupent 4 octets. Le processeur lira le deuxième octet de chaque instruction comme le début de la suivante et se comportera comme si tout programme était constitué de données aléatoires. - Mettre à jour le PC avant que la lecture de mémoire ne soit terminée. Le PC doit conserver l’adresse courante pendant la lecture de la mémoire. Mettez-le à jour au front d’horloge, pas de manière combinatoire.
- Oublier la réinitialisation. Sans fil de reset, un PC démarre avec la valeur aléatoire prise par les bascules à la mise sous tension. Reliez toujours la réinitialisation.
- Brancher vers un alignement invalide. L’alignement requis des instructions dépend de l’ISA et de ses extensions. Une machine qui n’accepte que des instructions alignées sur 32 bits rejette une cible telle que
0x1003; une ISA dotée de codages de 16 bits peut autoriser davantage de cibles. Appliquez la règle propre à l’architecture au lieu de figer une hypothèse universelle.
Construisez-le dans DigiSim
Ouvrez le modèle Exécuteur séquentiel d’instructions. Vous y verrez :
- Un bloc
PROGRAM_COUNTER_8BITen haut du chemin de lecture. - Un additionneur câblé pour ajouter systématiquement
1à chaque cycle d’horloge. - Un multiplexeur qui choisit entre
PC + 1et une adresse cible fournie par l’unité de commande. - Un interrupteur de réinitialisation qui force le PC à
0x00.
Faites avancer manuellement l’horloge et observez la progression du PC. Chargez ensuite un programme contenant une instruction de branchement et repérez l’instant où le multiplexeur passe de « séquentiel » à « cible » : ce seul bit est le flux de contrôle dans sa forme la plus pure.
La place du PC dans l’ensemble
Le compteur ordinal est un nœud du flux de données plus vaste du processeur. L’instruction qu’il désigne est capturée pour le traitement par le registre d’instruction et le décodeur. Les résultats arithmétiques peuvent mettre à jour les indicateurs du processeur, qu’une conception de branchement fondée sur des indicateurs consulte ensuite.
Lisez l’étude de cas du cycle lecture-décodage-exécution pour suivre la boucle complète, puis chargez le modèle Exécuteur séquentiel d’instructions et avancez pas à pas jusqu’à une instruction de branchement. La première fois que vous voyez le PC effectuer un saut non séquentiel, l’abstraction cesse d’être un schéma pour devenir un circuit.



