Así es como tu CPU ejecuta las instrucciones que le da el software

Una CPU lo que hace es ejecutar las instrucciones de un programa situado en una memoria. Pero, ¿sabíais que todos siguen las mismas normas generales? Todos siguen el mismo ciclo de instrucción, el cual se divide en tres etapas diferenciadas llamadas Fetch, Decode y Execute, las cuales se traducen como captación, descodificación y ejecución. Os explicamos como funcionan estas etapas y como se organizan.

Con tal de simplificar y hacer más entendible los conceptos explicados en este artículo hemos decidido describir un procesador sumamente simple para los tiempos que corren, por lo que en este artículo veréis una explicación de lo que son los ciclos de instrucción de manera generalizada que se puede aplicar desde los primeros procesadores de 8 bits a los más complejos que hay hoy en día

Visualizando el ciclo de instrucción

Ciclo Instrucción Unidad Control

Los procesadores no son diferentes desde cierto punto de vista a un motor de combustión, los cuales siempre realizan un proceso continuo de explosión del combustible en diferentes etapas, ya sean de 2 tiempos o de 4 tiempos. El motivo de ello es que los procesadores funcionan en tres etapas distintas en su versión más simple que son las siguientes:

  • Fetch o Captación: En la que la instrucción es captada desde la memoria RAM y copiada a dentro del procesador.
  • Decode o Descodificacion: En la que la instrucción previamente captada es descodificada y enviada a las unidades de ejecución
  • Execute o Ejecución: Donde la instrucción es resuelta y el resultado escrito en los registros internos del procesador o en una dirección de memoria de la RAM

Estas tres etapa se cumplen en todo procesador, existe una cuarta etapa que es la de Write-Back que es cuando las unidades de ejecución escriben el resultado, peor normalmente esto se cuenta dentro de la etapa de ejecución del ciclo de instrucción.

Primera etapa del ciclo de instrucción: Fetch

Fetch Process

La primera etapa del ciclo de instrucción se encarga de captar las instrucciones que hay en la memoria RAM asignada al procesador a través de una serie de unidades y registros que son las siguientes:

  1. Program Counter o Contador de Programa: El cual apunta a la siguiente línea de memoria donde se encuentra la siguiente instrucción del procesador. Se incrementa en 1 su valor cada vez que se termina un ciclo completo de instrucción o cuando una instrucción de salto cambia el valor del contador de programa.
  2. Memory Address Register o registro de direccionamiento de memoria: El MAR copia el contenido del PC y lo envía a la RAM a través de los pines de direccionamiento de la CPU, los cuales están cableados con los pines de direccionamiento de la propia memoria RAM.
  3. Memory Data Register o registro de datos a memoria : En el caso que la CPU tenga que realizar una lectura a memoria, lo que hace el MDR es copiar el contenido de esa dirección de memoria a un registro interno de la CPU, el cual es un registro temporal de paso antes de que su contenido sea copiado al Instruction Register. El MDR al contrario del MAR esta conectado a los pines de datos de la RAM y no a los de direccionamiento y en el caso de que se trate de una instrucción de escritura el contenido de lo que se quiere escribir en la RAM también se escribe en el MDR
  4. Instruction Register o Registro de Instrucción: La parte final de la etapa de captación o fetch es la escritura de la instrucción en el registro de instrucción, del cual la unidad de control del procesador copiará su contenido para la segunda etapa del ciclo de instrucción.

Estas 4 sub-etapas ocurren en todos los procesadores sea cual sea su utilidad, arquitectura y compatibilidad binaria o lo que llamamos ISA.

La unidad de control

Control Unit

La unidad de control es la pieza más compleja que existe en un procesador y sus tareas son las siguientes:

  • Se encargan de coordinar el movimiento y el orden en que de los datos que se mueven dentro y fuera del procesador, así de las diferentes subunidades que se encargan de ello.
  • En general se considera que las unidades de la etapa de captación o Fetch forman parte del hardware que llamamos unidad de control y dicho hardware es llamado también el Front-End de un procesador.
  • Interpreta las instrucciones y las envía a las diferentes unidades de ejecución a las que esta conectado.
  • Esta comunicado a las las diferentes ALUs y unidades de ejecución del procesador que actúan
  • Se encarga de captar y descodificar las instrucciones, sino también de escribir los resultados en los registros, caches o en la dirección correspondiente de la RAM.

Opcode-Mode-Adress

La unidad de control lo que hace es descodificar las instrucciones y esto lo hace porque cada instrucción en realidad no deja de ser una especie de oración en donde primero va el verbo y luego el objeto directo u objeto sobre el que se hace la acción. El sujeto se acaba eliminando en este lenguaje interno de los ordenadores por el hecho que se sobre-entiende que es el propio ordenador el que lo ejecuta, asi pues cada cantidad de bits es una oración donde los primeros 1 y 0 corresponden a la acción y los que vienen a continuación es el dato o la localización del dato que se quiere manipular.

La segunda etapa: Decode

Decodificación Instrucciones

Hay diferentes tipos de instrucciones y no todas hacen lo mismo, por lo que dependiendo del tipo de instrucción necesitamos saber hacía que unidades de ejecución se van a enviar y la manera más clásica de hacerlo es a través de lo que llamamos un descodificador, el cual toma cada instrucción, la divide internamente según el opcode o instrucción y el dato o la dirección de memoria donde se encuentra este.

Por ejemplo en el diagrama de arriba tenemos el diagrama de un procesador de solo 8 instrucciones, las cuales se pueden codificar en solo 3 bits. Cada una de las instrucciones una vez descodificadas se envían a las diferentes unidades de ejecución que las resolverán.

Este ciclo de instrucción es el más complejo de todo y el que define el tipo de arquitectura. Dependiendo si tenemos un conjunto de instrucciones reducido o complejo esto afectará a la naturaleza de la unidad de control, dependiendo del formato de la instrucción o de cuantas se procesen al mismo tiempo la fase de descodificación y por tanto la unidad de control tendrá una naturaleza u otra.

La forma más fácil de visualizar lo que ocurre es pensar en las instrucciones como trenes circulando a través de una compleja red ferroviaria y la unidad de control dirigiéndolos a una estación termino, la cual es la unidad de ejecución que se encargará de resolver la instrucción.

Tercera etapa: Execute

1 bit ALU

La última etapa es la de la ejecución de las instrucciones, en esta étapa las instrucciones son resueltas, pero no todos los tipos de instrucción se resuelven de la misma forma, ya que la forma de utilizar el hardware dependerá de la función de cada una de ellas, en general tenemos cuatro tipos de instrucciones:

  • Instrucciones de movimiento de bits: En el cual se manipula el orden de los bits que contienen el dato.
  • Instrucciones aritméticas: Donde se realizan operaciones matemáticas y también lógicas, estas se solucionan en las llamadas ALU o unidades aritmético-logicas
  • Instrucciones de salto: En la que se cambia la siguiente el valor del contador de programa, lo que permite utilizar el código de manera recursiva.
  • Instrucciones a memoria: Son con las que el procesador lee y escribe la información de la memoria del sistema.

El otro punto son los formatos de la instrucción, ya que una instrucción se puede aplicar a un dato, escalar o a varios datos al mismo tiempo, lo que conocemos como SIMD. Para terminar y dependiendo del formato de los datos, hay diferentes tipos de ALU para la ejecución de las instrucciones aritméticas, por ejemplo tenemos unidades de enteros y en coma flotante como unidades diferenciadas a día de hoy.

Una vez la instrucción ha sido terminada se escribe el resultado sobre una dirección de memoria en concreto y se pasa a ejecutar la siguiente, algunas instrucciones no manipulan los valores de memoria sino ciertos registros. Así pues el registro del contador de programa es modificado por las instrucciones de salto, si queremos leer o escribir un dato entonces se manipulan los registros MAR y MDR.