¿Cómo 'sabe' un procesador lo que significan los diferentes comandos?
Estoy pensando en comandos de nivel de ensamblaje como MOV, PUSH, CALL, etc.
¿Cómo 'sabe' un procesador lo que significan los diferentes comandos?
Estoy pensando en comandos de nivel de ensamblaje como MOV, PUSH, CALL, etc.
Respuestas:
Cuando una computadora interpreta instrucciones de nivel de ensamblaje , estas instrucciones se convierten en sus equivalentes binarios para que la CPU los lea. Cuando la CPU ejecuta las instrucciones, interpreta la parte del código de operación de la instrucción en "microprogramas" individuales, que contienen sus equivalentes de microcódigo . Para su información, una instrucción de ensamblaje completa consta de un código de operación y cualquier dato aplicable que lo acompañe, si es necesario (por ejemplo, nombres de registro, direcciones de memoria).
Las instrucciones de microcódigo tienen un nivel extremadamente bajo (más que el ensamblaje) y controlan las señales digitales reales que controlan el flujo de lógica en el microprocesador. Por ejemplo, una instrucción de microcódigo podría actualizar un indicador de registro de código de condición con un nuevo valor, o conectar un registro de CPU con una de las unidades ALU . Son posibles tareas más complejas, pero esto le muestra la idea general de para qué se utiliza el microcódigo.
El flujo general de la compilación a la ejecución es el siguiente. Las instrucciones de ensamblaje se ensamblan (se convierten en sus binarios equivalentes 0s y 1s, o de ahora en adelante, señales lógicas). Estas señales lógicas son interpretadas a su vez por la CPU, y se convierten en señales lógicas de bajo nivel que dirigen el flujo de la CPU para ejecutar la instrucción particular. Esto puede tomar uno o más ciclos de reloj, dependiendo de la arquitectura y el diseño del procesador (la mayoría de los manuales de referencia del procesador le indican cuántos ciclos de reloj se necesitan para ejecutar una instrucción en particular, como este, por ejemplo ).
Todo esto se realiza con un microcódigo programado (incrustado físicamente dentro del procesador en algún tipo de ROM , configurado durante la fabricación), que dirige el flujo a través de puertas lógicas de bajo nivel reales . Esto proporciona una interfaz entre las instrucciones de ensamblaje abstractas y la lógica eléctrica física en el procesador.
Entonces, en resumen, las instrucciones del procesador son ensambladas y cargadas por el procesador. El procesador usará estas instrucciones para buscar el microprograma (en forma de microcódigo) correspondiente a esa instrucción en particular, que es lo que "en realidad" ejecuta la instrucción. Una vez que se han ejecutado los microcódigos para la instrucción particular (que puede tomar uno o más ciclos de reloj), el procesador ejecuta el microcódigo para obtener la siguiente instrucción y el ciclo se repite.
El procesador realmente no "sabe" cuáles son los comandos. Los comandos son solo patrones binarios que hacen que el procesador haga lo que interpretamos que significan los comandos.
Por ejemplo, una operación ADD-R1-into-R2 hará que los valores de los registros 1 y 2 alcancen la ALU (unidad aritmética y lógica), haga que la ALU use la salida del sumador en lugar de las otras cosas, y hará que salida de la ALU para reemplazar el valor en el registro 2. Existen circuitos lógicos simples para lograr todas estas cosas ( multiplexor , sumador , contador , ...), aunque los procesadores reales utilizan optimizaciones muy complicadas.
Es como si estuvieras preguntando cómo sabe un auto reducir la velocidad cuando presionas los frenos. El automóvil no lo sabe, el pedal de freno simplemente controla indirectamente cómo se presionan las pastillas contra las ruedas.
Tomemos, por ejemplo, la instrucción que le dice a un procesador x86 / IA-32 que mueva un valor inmediato de 8 bits a un registro. El código binario para esta instrucción es 10110 seguido de un identificador de 3 bits para el registro que se utilizará. El identificador para el registro AL es 000, por lo que el siguiente código de máquina carga el registro AL con los datos 01100001.
10110000 01100001
Este código de computadora binario puede hacerse más legible para los humanos expresándolo en hexadecimal de la siguiente manera
B0 61
Aquí, B0 significa 'Mover una copia del siguiente valor a AL', y 61 es una representación hexadecimal del valor 01100001, que es 97 en decimal. El lenguaje ensamblador de Intel proporciona el MOV mnemónico (una abreviatura de movimiento) para instrucciones como esta, por lo que el código de máquina anterior se puede escribir de la siguiente manera en lenguaje ensamblador, completo con un comentario explicativo si es necesario, después del punto y coma. Esto es mucho más fácil de leer y recordar.
http://en.wikipedia.org/wiki/Assembler_language
En otras palabras, cuando 'ensamblas' tu programa de ensamblaje, tus instrucciones como
MOV AL, 61h
se convierten en números, que la CPU asocia un significado especial y luego actúa en consecuencia.
Lectura sugerida:
Consulte también las notas del curso de CS152: Arquitectura e ingeniería de computadoras en UC Berkeley, un curso en el que los estudiantes implementan una CPU.
Si buscas en Google "CPU casera", encontrarás muchas cosas buenas.
En el nivel más bajo extremo, todo lo que la CPU puede hacer es agregar. De la suma, puede restar, multiplicar y dividir (ya que estos son solo sumas de una manera diferente). La CPU usa esto para mover datos en la memoria aplicando las adiciones a las direcciones de memoria.
Sin embargo, tenga en cuenta que esto está en el nivel más bajo posible. De hecho, la CPU "comprende" ciertos comandos, en forma de microcódigo. Ver la respuesta de Breakthrough, está muy bien escrita.
He dado una respuesta relacionada en programmers.stackexchange.com, vea ¿Cómo funcionan las computadoras? donde caminé brevemente sobre todo desde cero sobre cómo las computadoras interpretan las instrucciones para mover los electrones.