El contador de programa (PC) es un contador binario que contiene la dirección de la siguiente instrucción a ejecutar. Por este motivo, a veces se lo denomina registro de dirección de instrucciones. La PC generalmente se incrementa justo después de que se haya recuperado la instrucción actual.
Suponiendo una memoria direccionable por bytes, en una máquina RISC, donde todas las instrucciones tienen la misma longitud (por ejemplo, 32 bits en el PIC32 basado en MIPS), entonces la PC se incrementará por la longitud de la instrucción (en este caso cuatro) después de cada instrucción. En un procesador CISC, como la serie Intel x86, donde las instrucciones pueden tener una longitud variable, entonces la PC se incrementará según el tamaño de la instrucción actual.
Algunas memorias de programa solo son direccionables por palabra, y las instrucciones solo pueden tener una o dos palabras, en cuyo caso la PC se incrementará en 1 o 2 respectivamente.
Los programas se ejecutan linealmente, a menos que se ejecute una instrucción de salto. Un salto incondicional siempre modifica la PC; un salto condicional modifica la PC solo si la condición establecida en la instrucción condicional (por ejemplo, el registro n es 0).
Una instrucción de salto puede contener la dirección de la siguiente instrucción a ejecutar, en cuyo caso la PC se sobrescribe con la dirección en la instrucción, o puede contener un valor relativo firmado, que se agrega al valor actual de la PC para obtener la siguiente dirección. Algunas veces estas últimas se denominan instrucciones de bifurcación. Pueden ser incondicionales o condicionales.
Para la arquitectura PIC32 MIPS, las instrucciones de salto guardan dos bits en el campo de dirección de la instrucción especificando solo la dirección de destino dividida por cuatro, ya que se sabe que todas las instrucciones están en un límite de cuatro bytes. De hecho, si se intentara saltar a una dirección que no estaba en un límite de cuatro bytes, se generaría una excepción de hardware.
Una instrucción de llamada o salto a subrutina también modifica la PC (por lo general, la dirección de la subrutina está contenida en la instrucción de llamada, aunque algunos procesadores también implementan una rama relativa a la instrucción de subrutina). La diferencia principal entre una instrucción de salto y una llamada de subrutina es que la PC generalmente se guarda en un stack , y al final de la subrutina, se ejecuta una instrucción de return que recupera este valor y lo coloca en la PC, por lo que el programa continúa ejecutándose inmediatamente después de la instrucción de llamada a la subrutina original.
A menudo, en microcontroladores más pequeños, solo se implementará un espacio de direcciones de programa de 16 bits, limitando el programa a 65536 bytes. Si se desea ir más allá de este límite, entonces se puede usar un esquema de paginación, con (por ejemplo) una "ventana" de 16K reservada en el espacio de direcciones de 64K, extendida a 128K bytes al proporcionar ocho páginas de 16K. Se utiliza un "registro de paginación" especial para seleccionar qué página está activa.