El contador de programa ( PC ), [1] comúnmente llamado puntero de instrucción ( IP ) en los microprocesadores Intel x86 e Itanium , y a veces llamado registro de dirección de instrucción ( IAR ), [2] [1] contador de instrucciones , [3] o solo parte del secuenciador de instrucciones, [4] es un registro del procesador que indica dónde se encuentra una computadora en la secuencia de su programa . [nota 1]
Por lo general, la PC se incrementa después de buscar una instrucción y mantiene la dirección de memoria (" apunta a") la siguiente instrucción que se ejecutará. [5] [nota 2]
Los procesadores generalmente obtienen instrucciones secuencialmente de la memoria, pero las instrucciones de transferencia de control cambian la secuencia colocando un nuevo valor en la PC. Estos incluyen bifurcaciones (a veces llamadas saltos), llamadas a subrutinas y retornos . Una transferencia condicionada a la verdad de alguna afirmación permite que la computadora siga una secuencia diferente en diferentes condiciones.
Una rama proporciona que la siguiente instrucción se obtenga de otro lugar de la memoria. Una llamada de subrutina no sólo se bifurca sino que guarda el contenido anterior de la PC en algún lugar. Un retorno recupera el contenido guardado de la PC y lo coloca nuevamente en la PC, reanudando la ejecución secuencial con la instrucción que sigue a la llamada a la subrutina.
En una unidad central de procesamiento (CPU) simple, la PC es un contador digital (que es el origen del término "contador de programa") que puede ser uno de varios registros de hardware . El ciclo de instrucciones [7] comienza con un fetch , en el que la CPU coloca el valor de la PC en el bus de direcciones para enviarlo a la memoria. La memoria responde enviando el contenido de esa ubicación de memoria en el bus de datos . (Este es el modelo de computadora con programa almacenado , en el que un único espacio de memoria contiene instrucciones ejecutables y datos ordinarios. [8] ) Después de la búsqueda, la CPU procede a la ejecución , tomando alguna acción basada en el contenido de la memoria que obtuvo. En algún momento de este ciclo, la PC se modificará para que la siguiente instrucción ejecutada sea diferente (normalmente, se incrementará para que la siguiente instrucción sea la que comienza en la dirección de memoria inmediatamente posterior a la última ubicación de memoria de la instrucción actual). .
Al igual que otros registros de procesador, la PC puede ser un banco de pestillos binarios, cada uno de los cuales representa un bit del valor de la PC. [9] El número de bits (el ancho de la PC) se relaciona con la arquitectura del procesador. Por ejemplo, una CPU de “32 bits” puede utilizar 32 bits para poder direccionar entre 2 y 32 unidades de memoria. En algunos procesadores, el ancho del contador del programa depende de la memoria direccionable; por ejemplo, algunos microcontroladores AVR tienen una PC que se reinicia después de 12 bits. [10]
Si la PC es un contador binario, puede incrementarse cuando se aplica un pulso a su entrada COUNT UP, o la CPU puede calcular algún otro valor y cargarlo en la PC mediante un pulso a su entrada LOAD. [11]
Para identificar la instrucción actual, la PC se puede combinar con otros registros que identifican un segmento o página . Este enfoque permite una PC con menos bits suponiendo que la mayoría de las unidades de memoria de interés se encuentran en la vecindad actual.
El uso de una PC que normalmente incrementa supone que lo que hace una computadora es ejecutar una secuencia generalmente lineal de instrucciones. Un PC de este tipo es fundamental para la arquitectura de von Neumann . Así, los programadores escriben un flujo de control secuencial incluso para algoritmos que no tienen por qué ser secuenciales. El " cuello de botella de von Neumann " resultante llevó a la investigación de la computación paralela , [12] incluidos modelos que no eran de von Neumann o de flujo de datos que no utilizaban una PC; por ejemplo, en lugar de especificar pasos secuenciales, el programador de alto nivel podría especificar la función deseada y el programador de bajo nivel podría especificarla utilizando lógica combinatoria .
Esta investigación también condujo a formas de hacer que las CPU convencionales basadas en PC funcionen más rápido, que incluyen:
Los lenguajes de programación modernos de alto nivel todavía siguen el modelo de ejecución secuencial y, de hecho, una forma común de identificar errores de programación es con una “ejecución de procedimiento” en la que el dedo del programador identifica el punto de ejecución como lo haría una PC. El lenguaje de alto nivel es esencialmente el lenguaje de máquina de una máquina virtual, [13] demasiado complejo para ser construido como hardware pero en cambio emulado o interpretado por software.
Sin embargo, los nuevos modelos de programación trascienden la programación de ejecución secuencial:
3.2.12. WRAPMODE […] AS asumirá que el contador de programa del procesador no tiene la longitud total de 16 bits dada por la arquitectura, sino una longitud que es exactamente suficiente para direccionar la ROM interna. Por ejemplo, en el caso del
AT90S8515
, esto significa 12 bits, correspondientes a 4 Kpalabras u 8 Kbytes. Esta suposición permite ramas relativas desde el principio hasta el final de la ROM y viceversa, lo que daría como resultado un error fuera de rama cuando se utiliza aritmética estricta. Aquí funcionan porque los bits de acarreo resultantes del cálculo de la dirección de destino se descartan. […] En el caso del AT90S8515 antes mencionado, esta opción es incluso necesaria porque es la única forma de realizar un salto directo a través del espacio de direcciones completo […]