pelicula logo language instruction informatica app assembly embedded cpu-architecture

logo - assembly pelicula



¿Cómo se convierte una instrucción de ensamblaje en cambios de voltaje en la CPU? (12)

He estado trabajando en C y CPython durante los últimos 3 a 5 años. Considera que mi base de conocimiento aquí.

Si tuviera que usar una instrucción de ensamblaje, como MOV AL, 61h a un procesador que la admite, ¿qué hay exactamente dentro del procesador que interpreta este código y lo distribuye como señales de voltaje? ¿Cómo se podría llevar a cabo una instrucción tan simple?

El montaje incluso se siente como un lenguaje de alto nivel cuando trato de pensar en la multitud de pasos contenidos en MOV AL, 61h o incluso XOR EAX, EBX .

EDITAR: Leí algunos comentarios preguntándome por qué puse esto como incrustado cuando la familia x86 no es común en los sistemas integrados. Bienvenido a mi propia ignorancia. Ahora supongo que si soy ignorante sobre esto, es probable que otros también lo ignoren.

Fue difícil para mí elegir una respuesta favorita considerando el esfuerzo que pusieron en sus respuestas, pero me sentí obligado a tomar una decisión. Sin sentimientos heridos, muchachos.

A menudo descubro que cuanto más aprendo sobre las computadoras, menos me doy cuenta de que realmente sé. ¡Gracias por abrirme a la lógica de microcódigos y transistores!

EDIT # 2: Gracias a este hilo, acabo de comprender por qué XOR EAX, EAX es más rápido que MOV EAX, 0h . :)


qué está exactamente dentro del procesador que interpreta este código y lo envía como señales de voltaje

Me gustaría decir ''hardware'', pero una respuesta más verdadera es '' microcode ''.


Bueno, aquí hay un resumen terriblemente asesinado :-)

Un MOV AL, 61h es nuevamente una forma de código legible por el ser humano que se alimenta al ensamblador. El ensamblador genera el hexcode equivalente que es básicamente una secuencia de bytes que el procesador entiende y que es lo que se almacenaría en la memoria. Entorno de sistema integrado, las secuencias de comandos del vinculador le dan un control detallado sobre dónde colocar estos bytes (áreas separadas para programas / datos, etc.) en la memoria.

El procesador contiene esencialmente una máquina de estado finito (microcódigo) implementada usando flip flops. La máquina lee (busca el ciclo) el código hexadecimal para ''MOV'' de la memoria, determina (ciclo de decodificación) que necesita un operando, que en este caso es 61h, lo recupera de la memoria y lo ejecuta (es decir, copias 61 en el registro del acumulador. ''Leer'' ''buscar'', ejecutar ''etc. significa que los bytes se desplazan / agregan dentro y fuera de los registros de desplazamiento usando circuitos digitales como sumadores, restadores, multiplexores, etc.


El borrador del libro "Diseño de microprocesador" se encuentra actualmente en línea en Wikilibros.

Espero que algún día incluya una excelente respuesta a esa pregunta. Mientras tanto, tal vez aún pueda aprender algo del borrador actual de una respuesta a esa pregunta, y nos ayude a hacer mejoras o al menos señalar cosas que olvidamos explicar y áreas donde la explicación es confusa.


El elemento más básico en un circuito digital debería ser Logic Gate . Las puertas lógicas se pueden usar para construir circuitos lógicos para realizar operaciones aritméticas booleanas , o decodificadores, o circuitos sequential como Flip-Flops . El Flip-Flop puede considerarse una memoria de 1 bit. Es la base de circuitos secuenciales más complejos, como contadores o registros (matrices de bits).

Un microprocessor es simplemente un conjunto de secuenciadores y registros. Las "instrucciones" para un microprocesador no son más que simples patrones de bits que se insertan secuencialmente en algunos de los registros, para activar secuencias específicas para realizar cálculos en "Datos". Los datos se representan como matrices de bits ... y ahora estamos en un nivel superior.



Esta es una pregunta que requiere más que una respuesta en para explicar.

Para aprender sobre esto desde los componentes electrónicos más básicos hasta el código de máquina básico, lea The Art of Electronics, por Horowitz y Hill . Para obtener más información sobre arquitectura de computadoras, lea Computer Organization and Design por Patterson y Hennessey . Si desea profundizar en temas más avanzados, lea Arquitectura de la computadora: un enfoque cuantitativo, por Hennessey y Patterson .

Por cierto, The Art of Electronics también tiene un manual de laboratorio complementario. Si tiene el tiempo y los recursos disponibles, recomendaría encarecidamente hacer los laboratorios; De hecho, tomé las clases impartidas por Tom Hayes, en las que creamos una variedad de circuitos analógicos y digitales, que culminaron en la construcción de una computadora a partir de un chip de 68k, algo de RAM, algunos PLD y algunos componentes discretos. Debería ingresar el código de la máquina directamente en la RAM usando un teclado hexadecimal; fue una maravilla, y una gran manera de obtener experiencia práctica en los niveles más bajos de una computadora.


Explicar todo el sistema en detalle es imposible hacerlo sin libros completos, pero aquí hay una descripción general de muy alto nivel de una computadora simplista:

  • En el nivel más bajo hay física y materiales (por ejemplo, transistores hechos de silicio dopado).
  • Utilizando física y materiales, puede derivar la puerta lógica NAND .
  • Usando la compuerta NAND, puede derivar todas las otras compuertas lógicas básicas (AND, OR, XOR, NOT, etc.) o, para mayor eficiencia, compilarlas directamente a partir de transistores, incluidas las versiones con más de 2 entradas.
  • Usando las puertas lógicas básicas, puede derivar circuitos más complicados, como el adder , el multiplexer , etc.
  • También utilizando las puertas lógicas básicas, puede derivar elementos de circuito digital con estado como el flip-flop , el clock , y así sucesivamente.
  • Usando sus circuitos señoriales más complicados, puede derivar piezas de mayor nivel como counters , memory , registers , la arithmetic-logic-unit , etc.
  • Ahora solo tienes que pegar tus piezas de alto nivel de manera que:
    • Un valor sale de la memoria
    • El valor se interpreta como una instrucción enviándolo al lugar apropiado (por ejemplo, la ALU o la memoria) usando multiplexores y etc. (los tipos básicos de instrucciones son lectura-de-memoria-en-registro, escritura-de-registro-en- memoria, perform-operation-on-registers, y jump-to-instruction-on-condition.)
    • El proceso se repite con la siguiente instrucción

Para comprender cómo una instrucción de ensamblaje causa un cambio de voltaje, simplemente necesita comprender cómo cada uno de esos niveles está representado por el nivel siguiente. Por ejemplo, una instrucción ADD causará que el valor de dos registros se propague a la ALU, que tiene circuitos que computan todas las operaciones lógicas. Luego, un multiplexor en el otro lado, que recibe la señal ADD de la instrucción, selecciona el resultado deseado, que se propaga de nuevo a uno de los registros.


He estado pensando en eso y buscando en Google como loco. La gente responde cosas como "el bla bla escribe en RAM", pero estoy realmente interesado en lo que significa "escribir".

Siempre comienzas escribiendo código, ¿verdad? Que luego se compila, ensambla, código de máquina, etc ... ¿cómo se convierte en voltajes en los transistores? ¡Pero espera! Retrocedamos un poco aquí. Cuando está escribiendo código, diga que quiere escribir "imprimir" Hola mundo "en cualquier idioma. En el momento en que presiona "p" (la primera letra de "imprimir") en su teclado, en realidad está reencaminando la corriente eléctrica que proporciona la toma de corriente de la pared a cierto conjunto de transistores. Entonces, en realidad ya está almacenando el 0V y + 5V en este paso. ¡No se genera más tarde!

Cómo se enjuagan estos voltajes en pasos posteriores es bueno ... ciencia eléctrica en todos los niveles.

Espero que esto responda a su pregunta.


Muy corto,

Una instrucción de código de máquina se almacena dentro del procesador como una serie de bits. Si busca MOV en la hoja de datos del procesador, verá que tiene un valor hexadecimal, como (por ejemplo) 0xA5, que es específico de la instrucción MOV ... (Hay diferentes tipos de instrucciones MOV con diferentes valores, pero ignorémoslo por el momento).

0xA5 hex == 10100101 binary.

* (Este no es un valor de código de operación real para MOV en un X86; solo estoy eligiendo un valor para fines ilustrativos).

Dentro del procesador, esto se almacena en un "registro", que en realidad es una matriz de flip-flops o pestillos, que almacenan un voltaje:

+5 0 +5 0 0 +5 0 +5

Cada uno de estos voltajes alimenta la entrada de una puerta o colección de puertas.

En el siguiente borde del reloj, esas puertas actualizan su salida en función de los voltajes de entrada del registro.

La salida de esas puertas alimenta a otro nivel de puertas, o de regreso a ellas mismas. Ese nivel se alimenta en el siguiente, que se alimenta en el siguiente, y así sucesivamente.

Eventualmente, una salida de puerta que pasa por la línea se conectará de nuevo a otro pestillo / flip-flop (memoria interna), o uno de los pines de salida en el procesador.

Register->(clock)->Gate A->(clock)->Gate B->pin ->latch

(ignorando los comentarios para diferentes tipos de puertas y estructuras de mayor nivel)

Estas operaciones ocurren en paralelo hasta cierto punto según lo definido por la arquitectura central. Una de las razones por las que los procesadores "rápidos" -digamos, 2.0GHz vs 1.0GHz- funcionan mejor es que una velocidad de reloj más rápida (el valor de GHz) resulta en una propagación más rápida de una colección de puertas a la siguiente.

Es importante entender que, en un nivel muy alto, todo lo que hace un procesador es cambiar voltajes de pin. Toda la gloriosa complejidad que vemos cuando usamos un dispositivo como una PC se deriva del patrón interno de puertas y los patrones en los dispositivos / periféricos externos conectados al procesador, como otras CPU, RAM, etc. La magia de una procesador son los patrones y secuencias en los que sus pines cambian los voltajes, y la retroalimentación interna que permite que el estado de la CPU en un momento contribuya a su estado en el siguiente. (En el ensamblaje, este estado se representa mediante banderas, el puntero / contador de instrucción, valores de registro, etc.)

De una manera muy real, los bits de cada código de operación (instrucción de código máquina) están físicamente atados a la estructura interna del procesador (aunque esto puede resumirse en cierto grado con una tabla de búsqueda interna / mapa de instrucciones donde sea necesario).

Espero que ayude. También tengo una buena educación de EE a mi cargo y una gran cantidad de experiencia de desarrollo integrado, por lo que estas abstracciones tienen sentido para mí, pero pueden no ser muy útiles para un neófito.


Recientemente comencé a leer el libro de Charles Petzold titulado Code, que hasta ahora cubre exactamente el tipo de cosas que supongo que te interesan. Pero no he podido leer todo el libro antes de comprar / pedir prestado.

Esta es mi respuesta relativamente corta, no Petzolds ... y con suerte en línea con lo que eran curiosidades.

Has oído hablar del transistor, supongo. La forma original de usar un transistor era para cosas como una radio de transistores. básicamente es un amplificador, toma la pequeña señal de radio que flota en el aire y la alimenta a la entrada del transistor que abre o cierra el flujo de corriente en un circuito próximo a él. Y conecta ese circuito con mayor potencia, por lo que puede tomar una señal muy pequeña, amplificarla y alimentarla en un altavoz, por ejemplo, y escuchar la estación de radio (hay más que aislar la frecuencia y mantener el transistor balanceado, pero tienes la idea, espero).

Ahora que existe el transistor que llevaba a era una forma de usar un transistor como un interruptor, como un interruptor de luz. La radio es como un interruptor de luz más tenue que puedes encender desde cualquier lugar, desde todo el camino hasta todo el camino. Un interruptor de luz sin atenuación está apagado o apagado, hay un lugar mágico en el medio del interruptor donde cambia. Usamos transistores de la misma manera en electrónica digital. Tome la salida de un transistor y alimente a otra entrada de transistores. La salida de la primera ciertamente no es una señal pequeña como la onda de radio, fuerza al segundo transistor en todo o completamente. eso conduce al concepto de TTL o lógica transistor-transistor. Básicamente tiene un transistor que impulsa un alto voltaje o le llamamos un 1, y en eso hunde un voltaje cero, llamemos a 0. Y arregla las entradas con otros componentes electrónicos para que pueda crear puertas Y (si ambas entradas son un 1, entonces la salida es un 1), O puertas (si una u otra entrada es un 1, entonces la salida es una). Inversores, NAND, puertas, puertas NOR (an o con un inversor), etc. Solía ​​haber un manual TTL y se podían comprar 8 o más fichas con una o dos o cuatro de algún tipo de puerta (NAND, NOR, AND, etc) funciona dentro, dos entradas y una salida para cada una. Ahora no necesitamos esos, es más barato crear lógica programable o chips dedicados con muchos millones de transistores. Pero todavía pensamos en términos de Y, O, y NO puertas para el diseño de hardware. (generalmente más como nand y nor).

No sé lo que enseñan ahora, pero el concepto es el mismo, para la memoria, un flip-flop puede considerarse como dos de estos pares TTL (NANDS) vinculados con la salida de uno que va a la entrada del otro. Vamos a dejar las cosas así. Eso es básicamente un bit único en lo que llamamos SRAM, o ram estático. sram toma básicamente 4 transistores. Dram o dinámico ram la memoria que pones en tu computadora tomas un transistor por bit, así que para empezar puedes ver por qué dram es lo que compras por gigabytes. Los bits de Sram recuerdan en qué los estableciste siempre que no se apaga. Dram comienza a olvidarse de lo que le dijiste tan pronto como lo dijiste, básicamente dram usa el transistor en una tercera forma diferente, hay algo de capacitancia (como en el condensador, no entraré en eso aquí) que es como una pequeña batería recargable, tan pronto como lo cargue y desenchufe el cargador, comenzará a drenar. Piense en una hilera de vasos en un estante con pequeños agujeros en cada vaso, estos son sus fragmentos, quiere que algunos de ellos sean uno para que tenga un asistente que llene los vasos que desea. Ese asistente tiene que llenar constantemente la jarra e ir por la fila y mantener los vasos "uno" lo suficientemente llenos con agua, y dejar que los vasos "cero" permanezcan vacíos. Para que en cualquier momento quieras ver cuáles son tus datos, puedes revisarlos y leer los ceros buscando niveles de agua que estén definitivamente por encima del medio siendo uno y los niveles definitivamente por debajo del medio sean cero. Así que incluso con el encendido, si el asistente no puede mantener las gafas lo suficientemente llenas como para distinguir una de cero, eventualmente parecerán ceros y se drenarán. Es la compensación de más bits por chip. Así que la historia corta aquí es que fuera del procesador usamos dram para nuestra memoria masiva, y hay una lógica asistente que se encarga de mantener los uno y cero. Pero dentro del chip, el registro AX y los registros DS, por ejemplo, mantienen sus datos usando flip flops o sram. Y por cada bit que conoces como los bits en el registro AX, es probable que haya cientos o miles o más que se utilizan para obtener los bits dentro y fuera de ese registro AX.

Usted sabe que los procesadores funcionan a cierta velocidad de reloj, estos días alrededor de 2 gigahertz o dos mil millones de relojes por segundo. Piensa en el reloj, que es generado por un cristal, otro tema, pero la lógica ve ese reloj como un voltaje que va alto y cero alto y cero a este ritmo de reloj de 2ghz o lo que sea (los avances de gameboy son 17mhz, viejos ipods alrededor de 75mhz, original ibm pc 4.77mhz).

Por lo tanto, los transistores utilizados como conmutadores nos permiten tomar voltaje y convertirlo en los ceros y los que conocemos tanto como ingenieros de hardware e ingenieros de software, y hasta llegar a darnos funciones lógicas Y, O y NO. Y tenemos estos cristales mágicos que nos permiten obtener una oscilación precisa de voltaje.

Así que ahora podemos hacer cosas como, por ejemplo, si el reloj es uno, y mi variable de estado dice que estoy en el estado de instrucción de búsqueda, entonces tengo que cambiar algunas puertas para que la dirección de la instrucción que quiero, que está en el el contador del programa, se apaga en el bus de memoria, de modo que la lógica de la memoria pueda darme mis instrucciones para MOV AL, 61h. Puede buscar esto en un manual x86 y descubrir que algunos de esos bits de código de operación dicen que se trata de una operación mov y el objetivo son los 8 bits inferiores del registro EAX, y la fuente del movimiento es un valor inmediato que significa que está en la ubicación de memoria después de esta instrucción. Entonces, debemos guardar esa instrucción / código de operación en algún lugar y buscar la siguiente ubicación de memoria en el siguiente ciclo de reloj. entonces ahora hemos guardado el mov, inmediato y tenemos el valor 61h leído de la memoria y podemos cambiar alguna lógica de transistor para que el bit 0 de ese 61h se almacene en el bit 0 flipflop de al y bit 1 a bit 1, etc. .

¿Cómo pasa todo lo que preguntas? Piensa en una función de python que realiza alguna fórmula matemática. comienzas en la parte superior del programa con algunas entradas a la fórmula que vienen como variables, tienes pasos individuales a través del programa que pueden agregar una constante aquí o llamar a la función de raíz cuadrada de una biblioteca, etc. Y en la parte inferior devuelve la respuesta. La lógica de hardware se hace de la misma manera, y hoy en día se usan lenguajes de programación, uno de los cuales se parece mucho a C. La principal diferencia es que las funciones de hardware pueden tener cientos o miles de entradas y la salida es un bit único. En cada ciclo de reloj, el bit 0 del registro AL se está calculando con un gran algoritmo dependiendo de qué tan lejos desee mirar. Piensa en la función de raíz cuadrada que llamaste para tu operación matemática, esa función en sí es una de estas, algunas entradas producen una salida y puede llamar a otras funciones, tal vez una multiplicación o división. Así que es probable que tenga un poco en alguna parte que pueda pensar como el último paso antes del bit 0 del registro AL y su función es: si el reloj es uno, entonces AL [0] = AL_next [0]; else AL [0] = AL [0]; Pero hay una función más alta que contiene ese próximo bit calculado a partir de otras entradas, y una función más alta y una función más alta y gran parte de ellas son creadas por el compilador de la misma manera que sus tres líneas de pitón pueden convertirse en cientos o miles de líneas de ensamblador. Algunas líneas de HDL pueden convertirse en cientos o miles o más transistores. la gente de hardware normalmente no mira la fórmula de nivel más bajo para un bit en particular para descubrir todas las entradas posibles y todos los AND, OR y NOT posibles para calcular más de lo que probablemente inspeccione el ensamblador generado por sus programas. pero podrías si quisieras.

Una nota sobre la microcodificación, la mayoría de los procesadores no usan microcodificación. se entra con el x86, por ejemplo, porque era un buen juego de instrucciones para su día, pero en la superficie lucha para mantenerse al día con los tiempos modernos. otros conjuntos de instrucciones no necesitan microcodificación y usan la lógica directamente en la forma que describí anteriormente. Puede pensar en la microcodificación como un procesador diferente que usa un conjunto de instrucciones / lenguaje de ensamblaje diferente que emula el conjunto de instrucciones que ve en la superficie. No es tan complicado como cuando intentas emular Windows en un Mac o Linux en Windows, etc. La capa de microcodificación está diseñada específicamente para el trabajo, puedes pensar que solo están los cuatro registros AX, BX, CX, DX, pero hay hay muchos más adentro. Y, naturalmente, ese programa de ensamblaje de alguna manera puede ejecutarse en múltiples rutas de ejecución en un núcleo o múltiples núcleos. Al igual que el procesador en su reloj despertador o lavadora, el programa de microcódigo es simple y pequeño, y se depuró y grabó en el hardware con la esperanza de que nunca necesite una actualización de firmware. Al menos idealmente pero al igual que su ipod o teléfono, por ejemplo, a veces quiere una solución de errores o lo que sea y hay una manera de actualizar su procesador (la bios u otro software carga un parche al arrancar). Supongamos que abre el compartimiento de la batería en el control remoto o la calculadora de su TV, es posible que vea un orificio donde pueda ver algunos contactos metálicos desnudos en una fila, tal vez tres o cinco o muchos. Para algunos controles remotos y calculadoras, si realmente lo deseaba, podría reprogramarlo, actualice el firmware. Normalmente, sin embargo, lo ideal es que el control remoto sea perfecto o lo suficientemente perfecto como para sobrevivir al televisor. La microcodificación proporciona la capacidad de obtener el producto muy complicado (millones, cientos de millones de transistores) en el mercado y solucionar los errores grandes y reparables en el campo más adelante. Imagínese un programa de 200 millones de líneas de python que su equipo escribió en, digamos, 18 meses y teniendo que entregarlo o la empresa no obtendrá el producto de la competencia. El mismo tipo de cosas, excepto una pequeña parte de ese código que puede actualizar en el campo, el resto debe permanecer tallado en piedra. para el despertador o la tostadora, si hay un error o si necesita ayuda, simplemente tírelo y obtenga otro.

Si busca en wikipedia o solo en Google, puede consultar los conjuntos de instrucciones y el lenguaje de máquina para cosas como el 6502, el z80, el 8080 y otros procesadores. Puede haber 8 registros y 250 instrucciones y puede tener una idea del número de transistores de que las 250 instrucciones de ensamblaje siguen siendo un lenguaje de muy alto nivel en comparación con la secuencia de puertas lógicas que se necesitan para calcular cada bit en un flip flop por reloj ciclo. Estás en lo correcto en esa suposición. A excepción de los procesadores microcodificados, esta lógica de bajo nivel no se puede reprogramar de ninguna manera; debe arreglar los errores de hardware con el software (para el hardware que se entregará y no se eliminará).

Busque el libro de Petzold, hace un excelente trabajo explicando cosas, muy superior a cualquier cosa que pueda escribir.



Editar: Aquí hay un ejemplo de CPU (6502) que se ha simulado usando python / javascript EN EL NIVEL DE TRANSISTOR http://visual6502.org Puedes poner tu código para ver cómo hace lo que hace.

Edit: Excelente vista de nivel de 10 000 m : Alma de una máquina nueva - Tracy Kidder

Tuve gran dificultad visualizando esto hasta que hice una microcodificación. Entonces todo tuvo sentido (en abstracto). Este es un tema complejo, pero en una vista de muy alto nivel.

Básicamente piensa en esto así.

Una instrucción de CPU es esencialmente un conjunto de cargas almacenadas en los circuitos eléctricos que componen la memoria. Hay un circuito que causa que esas cargas sean transferidas al interior de la CPU desde la memoria. Una vez dentro de la CPU, las cargas se configuran como entrada al cableado de los circuitos de la CPU. Esto es esencialmente una función matemática que provocará que ocurra más salida eléctrica, y el ciclo continúa.

Las CPU modernas son mucho más complejas pero incluyen muchas capas de microcodificación, pero el principio sigue siendo el mismo. La memoria es un conjunto de cargos. Hay un circuito para mover las cargas y otros circuitos para llevar a cabo la función con el resultado en otras cargas (salida) para alimentar a la memoria u otros circuitos para llevar a cabo otras funciones.

Para comprender cómo funciona la memoria, necesita comprender las puertas lógicas y cómo se crean a partir de múltiples transistores. Esto lleva al descubrimiento de que el hardware y el software son equivalentes en el sentido de que esencialmente realizan funciones en el sentido matemático.