Un compteur de programme (PC) est un registre qui stocke l'emplacement où un programme informatique est exécuté par un processeur . Il est également couramment appelé pointeur d'instruction (IP) dans les microprocesseurs Intel x86 et Itanium , et parfois appelé registre d'adresse d'instruction (IAR), le compteur d'instructions , ou simplement une partie du séquenceur d'instructions.
Généralement, le compteur ordinal (PC) stocke l' adresse mémoire d'une instruction . De plus, il est généralement incrémenté après le chargement d'une instruction et pointe donc vers l'instruction suivante à exécuter. Pour un processeur qui s'incrémente avant le chargement, le PC pointe vers l'instruction en cours d'exécution. Sur certains processeurs, le PC pointe à une certaine distance au-delà de l'instruction courante. Par exemple, sur l' ARM7 , la valeur du PC visible par le programmeur reflète la prélecture de l'instruction et correspond à l'adresse de l'instruction courante plus 8 en mode ARM, ou plus 4 en mode Thumb. Pour les processeurs modernes, la localisation de l'exécution dans le programme est complexifiée par le parallélisme au niveau des instructions et l'exécution hors séquence .
Par défaut, un processeur extrait les instructions de la mémoire de manière séquentielle . Une instruction de transfert de contrôle (CTC) modifie cette séquence en écrivant une valeur dans le compteur ordinal (PC). Un branchement permet d'extraire l'instruction suivante d'une autre zone de la mémoire. Un appel de fonction non seulement provoque un branchement, mais sauvegarde également la valeur du PC. Un retour restaure la valeur du PC pour reprendre l'exécution à l'instruction suivant l'appel, en effectuant un branchement vers la valeur sauvegardée. Un transfert conditionnel permet à l'ordinateur de suivre une séquence différente selon les conditions.
processeur simple , le compteur de programme (PC) est un compteur numérique (à l'origine du terme « compteur de programme ») qui peut être un registre matériel . Le cycle d'instruction commence par une phase de lecture , durant laquelle le processeur place la valeur du PC sur le bus d'adresses pour l'envoyer à la mémoire. La mémoire répond en envoyant le contenu de cette adresse mémoire sur le bus de données . (Il s'agit du modèle d'ordinateur à programme enregistré , dans lequel un seul espace mémoire contient à la fois les instructions exécutables et les données ordinaires ). Après la lecture, le processeur procède à l'exécution , en effectuant une action en fonction du contenu mémoire obtenu. À un moment donné de ce cycle, le PC est modifié afin que l'instruction suivante exécutée soit différente (généralement, incrémenté pour que l'instruction suivante soit celle commençant à l'adresse mémoire suivant immédiatement la dernière adresse mémoire de l'instruction courante).Comme les autres registres du processeur, le compteur de programme (PC) peut être constitué d'un ensemble de verrous binaires, chacun représentant un bit de sa valeur. Le nombre de bits (la largeur du PC) dépend de l'architecture du processeur. Par exemple, un processeur « 32 bits » peut utiliser 32 bits pour adresser 2<sup> 32</sup> unités de mémoire. Sur certains processeurs, la largeur du compteur de programme dépend plutôt de la mémoire adressable ; par exemple, certains microcontrôleurs AVR possèdent un PC qui se réinitialise après 12 bits.
Si le PC est un compteur binaire, il peut s'incrémenter lorsqu'une impulsion est appliquée à son entrée COUNT UP, ou le CPU peut calculer une autre valeur et la charger dans le PC par une impulsion sur son entrée LOAD.
Pour identifier l'instruction courante, le compteur ordinal (PC) peut être combiné avec d'autres registres identifiant un segment ou une page . Cette approche permet d'utiliser un PC avec moins de bits en supposant que la plupart des unités de mémoire pertinentes se trouvent à proximité de l'instruction courante.
Conséquences sur l'architecture des machines
L'utilisation d'un compteur ordinal (PC) à incrémentation linéaire suppose que l'ordinateur exécute une séquence d'instructions généralement linéaire. Ce PC est au cœur de l' architecture de von Neumann . Par conséquent, les programmeurs conçoivent un flux de contrôle séquentiel , même pour des algorithmes qui ne sont pas nécessairement séquentiels. Le « goulot d'étranglement de von Neumann » qui en résulte a conduit à des recherches sur le calcul parallèle , notamment sur des modèles non-von Neumann ou de flux de données n'utilisant pas de PC. Par exemple, au lieu de spécifier des étapes séquentielles, le programmeur de haut niveau peut définir la fonction souhaitée , tandis que le programmeur de bas niveau peut la spécifier à l'aide d' une logique combinatoire .
Ces recherches ont également permis de trouver des moyens d'accélérer le fonctionnement des processeurs classiques pour PC, notamment :
- Le pipeline , dans lequel différents composants matériels du processeur exécutent simultanément différentes phases de plusieurs instructions.
- L' architecture VLIW ( Very Long Instruction Word ), où une seule instruction peut réaliser plusieurs effets.
- Techniques permettant de prédire l'exécution hors séquence et de préparer les instructions suivantes pour une exécution en dehors de la séquence régulière.
Conséquences dans la programmation de haut niveau
Les langages de programmation modernes de haut niveau suivent toujours le modèle d'exécution séquentielle et, de fait, une méthode courante pour identifier les erreurs de programmation consiste à effectuer une « exécution de procédure » où le programmeur repère le point d'exécution du doigt, comme le ferait un ordinateur. Le langage de haut niveau est essentiellement le langage machine d'une machine virtuelle , trop complexe pour être implémentée matériellement, mais donc émulée ou interprétée par logiciel.
Cependant, les nouveaux modèles de programmation transcendent la programmation à exécution séquentielle :
- Lors de l'écriture d'un programme multithread , le programmeur peut écrire chaque thread comme une séquence d'instructions sans préciser le moment d'exécution de chaque instruction par rapport aux instructions des autres threads.
- En programmation événementielle , le programmeur peut écrire des séquences d'instructions pour répondre à des événements sans spécifier de séquence globale pour le programme.
- En programmation de flux de données , le programmeur peut écrire chaque section d'un pipeline de calcul sans spécifier le timing par rapport aux autres sections.