opcodes ISA --- ¿De dónde vienen?

12

Cuando los ingenieros están diseñando una arquitectura de conjunto de instrucciones, por qué procedimiento o protocolo, si los hay, siguen al designar ciertos códigos binarios como instrucciones. Por ejemplo, si tengo una ISA que dice que 10110 es una instrucción de carga, ¿de dónde proviene ese número binario? ¿Se modeló a partir de una tabla de estados para una máquina de estados finitos que representa una operación de carga?

Editar: Después de investigar más, creo que lo que estoy tratando de preguntar es sobre cómo se asignan los códigos de operación para las distintas instrucciones de la CPU. ADD podría designarse con un código de operación de 10011; una instrucción de carga podría designarse como 10110. ¿Qué proceso de pensamiento se utiliza para asignar estos códigos de operación binarios para el conjunto de instrucciones?

    
pregunta Steven

7 respuestas

5

En muchos casos, la elección es bastante arbitraria o se basa en "donde mejor se adapte" a medida que las ISA crecen con el tiempo. Sin embargo, el MOS 6502 es un maravilloso ejemplo de un chip en el que el diseño de ISA se vio muy influenciado al tratar de exprimir lo más posible los transistores limitados.

Echa un vistazo a este video que explica cómo el 6502 se diseñó mediante ingeniería inversa , especialmente a partir de 34:20.

El 6502 es un microprocesador de 8 bits introducido en 1975. Aunque tenía un 60% menos de puertas que el Z80, era el doble de rápido y, aunque estaba más limitado (en términos de registros, etc.), lo compensaba. que con un conjunto de instrucciones elegante.

Contiene solo 3510 transistores, que fueron extraídos, a mano , por un pequeño equipo de personas que se arrastraban sobre unas grandes láminas de plástico que luego se contrajeron ópticamente, formando las distintas capas del 6502. .

Como puede ver a continuación, el 6502 pasa el código de operación y los datos de temporización a la ROM de decodificación, luego lo pasa a un componente de "lógica de control aleatorio" cuyo propósito es probablemente anular la salida de la ROM en ciertas situaciones complejas.

Alas37:00enelvideo,puedesverunatabladelaROMdedecodificaciónquemuestraquécondicionesdebencumplirlasentradasparaobtenerun"1" para una salida de control determinada. También puede encontrarlo en esta página .

Puedes ver que la mayoría de las cosas en esta tabla tienen X en varias posiciones. Tomemos por ejemplo

011XXXXX 2 X RORRORA

Esto significa que los primeros 3 bits del código de operación deben ser 011, y G debe ser 2; Nada más importa. Si es así, la salida llamada RORRORA se volverá verdadera. Todos los opcodes ROR comienzan con 011; pero hay otras instrucciones que comienzan con 011 también. Probablemente sea necesario filtrarlos con la unidad de "lógica de control aleatorio".

Básicamente, los códigos de operación se eligieron de modo que las instrucciones que necesitaban hacer lo mismo entre sí tuvieran algo en común en su patrón de bits. Puede ver esto mirando una tabla de códigos de operación ; todas las instrucciones OR comienzan con 000, todas las instrucciones de la Tienda comienzan con 010, todas las instrucciones que utilizan direccionamiento de página cero tienen el formato xxxx01xx. Por supuesto, algunas instrucciones no parecen "ajustarse", porque el objetivo no es tener un formato de código de operación completamente regular, sino proporcionar un conjunto de instrucciones poderoso. Y es por esto que la "lógica de control aleatorio" era necesaria.

La página que mencioné anteriormente dice que algunas de las líneas de salida en la ROM aparecen dos veces, "Suponemos que esto se hizo porque no tenían forma de enrutar la salida de alguna línea donde querían, así que colocaron la misma línea en un lugar diferente de nuevo ". Solo puedo imaginar a los ingenieros dibujando a mano las puertas una por una y de repente dándome cuenta de un defecto en el diseño y tratando de encontrar una manera de evitar reiniciar todo el proceso.

    
respondido por el Artelius
22

Depende de la edad de la ISA.

En los primeros días del diseño manual, y más aún cuando las CPU se ensamblaban a partir de lógica discreta, el diseño lógico debería haber sido primero, minimizado en gran medida, y luego los patrones de bits ISA habrían sido los valores necesarios para hacer que la lógica mínima funcione.

Por lo tanto, puede haber un patrón particular de señales de control que permita a algunos multiplexores conectar la salida de ALU a la entrada del archivo de registro de GP, unas pocas señales de control más que ordenan a la ALU que agregue, reste, AND, OR, etc. y unos pocos bits de dirección en el archivo de registro. Estos tres grupos de señales formarán campos dentro de la instrucción. Cada grupo se mantendrá unido, y su significado detallado surge del diseño para esa unidad (ALU, etc.) pero los grupos pueden estar en cualquier orden, hasta que usted diseñe el decodificador de instrucciones. (El x86 tiene la edad suficiente para que puedas detectar algo de esto si miras en el lugar correcto, no era un diseño totalmente nuevo, pero se extrajo del 8080 más antiguo)

Las ISA posteriores pueden "limpiarse" y hacerse más regulares y fáciles de usar, con hardware para traducir entre ellas y las señales de control de nivel de hardware reales, a veces a través de "microcódigo". Estos se denominan "CISC" o "Codificación de conjunto de instrucciones complejas". El prefijo de instrucción x86 "Rep" es un ejemplo simple de esto: hace que la siguiente instrucción se repita varias veces, para evitar tener que escribir un bucle FOR.

Más tarde (en la década de 1980) regresó a un estilo más simple de codificación directa (RISC - Reduced Instruction Set Coding) que puede ver en los procesadores ARM. Esto fue impulsado por el pequeño tamaño de los ASIC en ese momento, y el deseo de colocarles CPU de 32 bits, por lo que no había capacidad adicional para decodificadores de conjuntos de instrucciones complejos, para que la CPU completa llegara a aproximadamente 20,000 compuertas. (También hubo un aumento temporal del rendimiento, ya que la gente no había desarrollado técnicas para hacer que los decodificadores CISC fueran rápidos, lo que se produjo alrededor de 1995 con el Pentium Pro)

Y hoy en día no importa: las CPUs leen varias instrucciones a la vez y dedican millones de transistores a decodificarlas, reordenarlas y ejecutar la mayor cantidad posible a la vez, para acelerar los programas que se hayan escrito. para el estilo más antiguo de ISA.

    
respondido por el Brian Drummond
9

Si agrupas instrucciones similares juntas, surgirán patrones. Esto es muy obvio en ARM, donde el manual de ISA en realidad muestra qué parte de una palabra de instrucción corresponde a función, opción de registro, etc. Pero también puede inferirse para X86 .

En última instancia, la parte de "función" de los códigos de operación se integra en algún decodificador binario-a-uno que realmente activa una función particular o una secuencia de operaciones canalizadas. No suelen estar relacionados con el contenido de ninguna máquina de estados, a menos que estemos considerando instrucciones de longitud variable que requieren una máquina de estados para descodificar.

    
respondido por el pjc50
6

Alguien en algún momento se sentó y los definió.

Una buena ISA hará que el decodificador sea lo más simple posible.

Por ejemplo, con una instrucción ALU, podría permitir que algunos bits del código de operación se envíen directamente a las líneas de control de la ALU.

    
respondido por el ratchet freak
5

Normalmente, dividiría su ISA en grupos funcionales. Tiene sentido (ya sea para la optimización lógica o simplemente para ser ordenado) que los pares complementarios se diferencian por un solo cambio de bit (carga frente a almacenamiento), y que tiene alguna jerarquía de bits que afecta al árbol de decisión de decodificación.

Al final del día, una asignación arbitraria de bits para el bloque de funciones (en lugar de colocar los campos de 'datos' en la instrucción solo tendrá un pequeño impacto en su eficiencia de diseño general, pero tiene muchas opciones sobre cómo "optimizar" su codificación ISA según lo que crea que es un parámetro importante.

    
respondido por el Sean Houlihane
1

La codificación de instrucciones es un compromiso feo entre.

Haciendo que la decodificación sea simple, para esto desea un conjunto simple de campos, cada uno de los cuales puede decodificarse por separado y enrutarse a una parte separada del motor de ejecución.

Empaque tanta funcionalidad como sea posible en un tamaño limitado de palabra de instrucción. Esto lleva a cosas como formatos constantes especiales que pueden codificar una variedad de números comunes.

Compatibilidad hacia adelante y hacia atrás. Si asigna funcionalidad a cada código de operación posible, no se da espacio para expandir la arquitectura más adelante. Si está agregando a una arquitectura existente, debe insertar sus nuevas instrucciones en los códigos de operación de repuesto.

    
respondido por el Peter Green
1

Randy Hyde's excelente (aunque algo anticuado) El Arte de la Asamblea va en el conjunto de instrucciones x86 en detalle en el capítulo 3.3.4 La unidad de control y los conjuntos de instrucciones y siguientes.

  

Los programas en los primeros sistemas informáticos (previos a Von Neumann) a menudo estaban "conectados" a los circuitos. Es decir, el cableado de la computadora determinó qué problema resolvería la computadora. Uno tuvo que volver a cablear los circuitos para cambiar el programa. Una tarea muy difícil. El siguiente avance en el diseño de computadoras fue el sistema de computadora programable, uno que le permitió a un programador de computadoras "reconfigurar" fácilmente el sistema de computadora usando una secuencia de enchufes y cables de conexión. Un programa de computadora consistía en un conjunto de filas de agujeros (sockets), cada fila representa una operación durante la ejecución del programa. El programador puede seleccionar una de varias instrucciones conectando un cable a la toma particular para obtener la instrucción deseada.

A continuación, demuestra bastante pegadizo y, al fin, cómo los primeros enchufes representan la instrucción, los siguientes codifican la fuente y el destino. Por supuesto, hoy ya nadie "conecta", pero para los ISA realmente antiguos, los bits en el código de operación básicamente hacen el mismo trabajo que antes.

Terminas con algo como esto:

    
respondido por el DevSolar

Lea otras preguntas en las etiquetas