¿Cómo pasamos exactamente de conjuntos binarios / hexadecimales a instrucciones de ensamblaje?

13

Así que he estado tratando de aprender algo de programación Embedded / Assembly por un tiempo aquí últimamente, además de tratar de aprender el nivel más bajo (puertas y demás).

Sin embargo, una cosa me desconcierta ... es cómo "obtenemos" conjuntos de instrucciones. Entiendo un poco cómo funcionan las puertas / TTL y tales, pero no veo cómo pasamos de eso a mover, agregar, clr, etc.

Probablemente sea una pregunta estúpida ... pero quiero decir que pienso en los primeros microprocesadores / controladores y pienso ... ¿cómo diseñaron exactamente un conjunto de instrucciones y lo hicieron funcionar?

editar: Supongo que para Clarity, imagina que estoy hablando del primer microprocesador, ¿cómo pasaron de Binary a crear un conjunto de instrucciones?


fuente
2
Cada instrucción tiene un valor, el compilador convierte su código en estas instrucciones, en función de cómo está estructurado su código.
Ramhound
1
No estoy seguro si entiendo su pregunta perfectamente, pero creo que puede encontrar su respuesta aquí , aquí o aquí .
e-MEE
3
¿Cómo pasaron de Binario a crear realmente un Conjunto de Instrucciones? En realidad, "ellos" no lo hicieron, es al revés, al menos en general. Los diseñadores de CPU determinan las operaciones que realizará la CPU, luego crean el conjunto de instrucciones a partir de eso y luego asignan las instrucciones (mnemotécnicas) a los códigos de operación (código de máquina binario). @Scott Whitlock proporcionó una buena respuesta a continuación, solo quería abordar la última parte de su pregunta porque su suposición, al menos en mi experiencia, es al revés.
Radian
1
Este muy buen libro: www1.idc.ac.il/tecs es lo que me explicó todo, la mayoría de los capítulos están disponibles en línea de forma gratuita. Usted diseña su propio chip (en un lenguaje descriptivo de hardware simple) desde nand gates, luego un ensamblador y luego un compilador, luego escribe un sistema operativo en el idioma que creó. ¡Cosas increíbles, y como alguien sin un título en ciencias, fue un tiempo bien invertido para mí!
bplus el

Respuestas:

18

El corazón de una CPU es la ALU . Es responsable de tomar una instrucción (como MOV) que es solo una serie predefinida de dígitos binarios, y también tomar 0, 1 o 2 operandos, y realizar la operación correspondiente en ellos. La instrucción más simple podría ser un NOP (sin operación) que esencialmente no hace nada. Otra operación típica es ADD (agrega dos valores).

La ALU lee y escribe datos desde y hacia "registros". Estas son pequeñas ubicaciones de memoria internas de la CPU. Parte de la instrucción (2 a 3 bits para cada entrada, dependiendo de cuántos registros tenga) indica de qué registro leer. Hay unidades en la CPU externas a la ALU que se encargan de cargar los datos requeridos (y las instrucciones) de la memoria a los registros, y escribir el resultado de los registros nuevamente en la memoria. La ubicación para escribir el resultado también se codificará en otros 2 o 3 bits.

La elección de "códigos operativos", que es el número binario que representa una operación, no es arbitraria. Los códigos de operación bien elegidos reducen la complejidad de la ALU. Cada bit o grupo de bits tiende a habilitar y deshabilitar ciertas puertas lógicas en la ALU. Por ejemplo, una instrucción ADD tendría que habilitar la etapa de salida para elegir el resultado de la lógica de adición interna. Del mismo modo, una instrucción MUL elegiría el resultado de la lógica de multiplicación. Dependiendo del diseño, es muy probable que tanto el sumador como los circuitos de multiplicación realicen su operación en los operandos de entrada, y es solo la selección de salida (lo que se escribe en los bits de salida de la ALU) lo que cambia.

Scott Whitlock
fuente
1
Supongo que lo que pregunto es cómo eligen. ¿Y cómo hacen para asignarlo?
1
@Sauron: vuelva a leer el tercer párrafo e intente comprender la aritmética binaria y los circuitos digitales. Puedo representar un conjunto de instrucciones con 256 instrucciones por una línea de 8 bits en un circuito digital. Eso significa que necesito 8 puertos io en mis dispositivos de hardware para transferir todos los estados posibles (2 estados por línea ^ 8 líneas = 256 estados posibles). La unidad de procesamiento puede decidir qué hacer con esa señal de entrada digital. Un circuito digital significa que tiene dos estados de hardware: Hi y Lo, voltaje o sin voltaje. De ahí viene el binario. La representación binaria es la más cercana al metal.
Falcon
3
@Sauron: busque Multiplexores digitales para ver cómo un circuito digital puede elegir entre uno de varios valores. Si tiene un bus de 8 bits, solo necesita 8 de estos multiplexores digitales binarios en paralelo.
Scott Whitlock
1
@ Falcon Ok ....... Creo que eso tiene más sentido. Siempre olvido que al final todo se reduce a señales binarias ... e incluso una instrucción como "mov" todavía se representa como binaria.
1
@Sauron: investiga un poco sobre la CPU, te ayudará a comprender qué son los códigos operativos y cómo funcionan. Por qué se eligen ciertos códigos de operación no es importante, incluso hacer la pregunta "por qué" no tiene mucho sentido. Comprender cómo se eligen podría ayudarlo a comprender más sobre la CPU y su estructura.
Ramhound
9

Tomaré tu pregunta literalmente y hablaré sobre todo de microprocesadores, no de computadoras en general.

Todas las computadoras tienen algún tipo de código de máquina. Una instrucción consta de un código de operación y uno o más operandos. Por ejemplo, la instrucción ADD para el Intel 4004 (el primer microprocesador) se codificó como 1000RRRR donde 1000 es el código de operación para ADD y RRRR representaba un número de registro 0-15 (font>1111 en binario).

Todas las demás instrucciones que hacen referencia a uno de los 16 registros de 4 bits (como INC, ISZ, LD, SUB, XCHG) también usan los 4 bits bajos para codificar el número de registro y varias codificaciones de los 4 bits superiores para especificar El código de operación. Por ejemplo, ADD, SUB, LD y XCHG utilizan los códigos de operación 1000, 1001, 1010 y 1011 (todos en binario) combinados con el campo de registro. Entonces puede ver cómo se usa un patrón para simplificar la lógica.

Los primeros programas de computadora se escribieron a mano, codificando a mano los 1 y 0 para crear un programa en lenguaje de máquina. Esto se programó en una ROM (memoria de solo lectura). Ahora, los programas generalmente se escriben en la memoria Flash borrable eléctricamente, en el caso de los microcontroladores, o se quedan sin RAM, si los microprocesadores. (Este último todavía necesita algún tipo de memoria de solo lectura para arrancar).

El lenguaje de máquina se vuelve tedioso muy rápido, por lo que se desarrollaron programas de ensamblador que toman un lenguaje de ensamblador mnemónico y lo traducen, generalmente una línea de código de ensamblaje por instrucción, en código de máquina. Entonces, en lugar de 10000001, uno escribiría ADD R1.

Pero el primer ensamblador tuvo que escribirse en código máquina. Entonces podría reescribirse en su propio código de ensamblador, y la versión en lenguaje de máquina solía ensamblarlo la primera vez. Después de eso, el programa podría ensamblarse a sí mismo (esto se llama bootstrapping).

Dado que el primer microprocesador se desarrolló mucho después de que existieran los mainframes y las minicomputadoras, y el 4004 no era realmente adecuado para ejecutar un ensamblador de todos modos, Intel probablemente escribió un ensamblador cruzado que se ejecutó en una de sus computadoras grandes, y tradujo el código de ensamblaje para el 4004 en una imagen binaria que podría programarse en la ROM.

tcrosley
fuente
4

Una computadora en un nivel muy bajo puede ser representada por una ruta de datos y control . Buscar en Google juntos puede darle mucha lectura, ya que es fundamental en la arquitectura / diseño digital.

Haré todo lo posible para resumir:

Como se mencionó aquí, en el fondo tenemos una ALU: lo que se debe saber sobre la ALU (y otras partes de la CPU) es que es reconfigurable para diferentes operaciones. Más específicamente, tenemos la capacidad de reconfigurar la ruta de datos , que es cómo se obtienen los parámetros, qué operación hacer y dónde se almacenan después. Imagina poder manipular estas tres cosas: este es nuestro control .

Entonces, ¿cómo logramos esto? Como ya se mencionó nuevamente, podemos aprovechar la lógica digital de bajo nivel y crear multiplexores para diferentes rutas. Los multiplexores se controlan utilizando un conjunto de bits para la entrada: ¿de dónde se toman estos bits? Codificado de las instrucciones mismas. La conclusión: instrucciones como mov, add, etc. son solo un conjunto de bits que le indican a la CPU cómo configurar su ruta de datos para una operación en particular. Lo que estás leyendo (mov, add) es la forma legible por humanos (lenguaje ensamblador) y nuestro programa define un procedimiento de rutas de datos y operaciones.

Pido disculpas si esto es una simplificación excesiva de procesos más complejos para aquellos que tienen más conocimiento en esta área. Para su información, el intercambio de pila de ingeniería eléctrica sería un gran lugar para hacer esta pregunta, ya que se trata de una lógica de muy bajo nivel.

Jon
fuente
3

Si entiendo su pregunta, no entiendo cómo se relacionan bin / hex o ensamblaje.

Supongo que el meollo de su pregunta es cómo llego desde las puertas básicas, Y, O, NO a instrucciones como mover, cargar, almacenar, agregar, etc.

Tengo mi propio pequeño conjunto de instrucciones de enseñanza que hice desde cero que tiene algunos de los detalles de decir cómo sumar y restar el trabajo de puertas básicas y cosas así http://github.com/dwelch67/lsasim .

Busque el libro Código (algo, algo, algo) de Petzold. Puede comenzar en la primaria, pero lo lleva lentamente de nada que ver con computadoras y dispositivos electrónicos a binario, hexadecimal, a las puertas básicas, etc.

¿Estás preguntando cómo construirías uno desde cero hoy, o cómo lo hicieron en el día? Hoy comenzaría con una definición del conjunto de instrucciones. simplemente te sientas y lo escribes, piensas en los tipos de instrucciones que debes tener, las cargas, las tiendas, los movimientos y todo lo demás, y luego cuántos registros, qué tan grandes son los registros, esto en parte afecta el tamaño de la instrucción, crees sobre el tamaño de la instrucción ...

Déjame parar y preguntarte cómo escribes un programa? ¿Comenzando con una pantalla en blanco en un editor de texto? Tienes una idea de la tarea que estás tratando de resolver las variables que podrías necesitar, las funciones, el lenguaje de programación, etc. Y cada persona es diferente, pero en cierta medida haces un poco de esto (por ejemplo, definir y escribir funciones), un poco de eso (hacer archivos de encabezado con definiciones reutilizables y enumeraciones y estructuras y cosas), y un poco de lo otro (solo código, llenar las funciones con variables y código). Y circula por las diferentes tareas, al final siente que tiene un equilibrio de tamaño de código, velocidad, legibilidad, calidad, funcionalidad, etc. No es diferente con el diseño de hardware. los diseñadores de hardware también usan lenguajes de programación (vhdl, verilog) y pasan por el mismo proceso,

Al igual que con un programa de software, equilibra los deseos, el rendimiento, el tamaño, las características, etc. Es posible que se le impongan algunas reglas de diseño que desea o que su jefe le obligó a hacer, etc. Al igual que con el diseño de software mucho después el diseño inicial en la implementación puede descubrir que tiene algunos grandes errores y que tiene que volver al diseño inicial y cambiar el conjunto de instrucciones, grandes o pequeños cambios. Podría llegar a tener un compilador y un procesador simulado para encontrar que realmente necesita un par de instrucciones específicas que mejoren drásticamente la calidad del código compilado, el rendimiento, etc.

Entonces, ha inventado un conjunto de instrucciones desde cero, ha utilizado cierta experiencia con el diseño de hardware para agrupar instrucciones similares con patrones de bits similares para que puedan decodificarse más fácilmente, no solo para la programación del lenguaje de hardware, sino que ahorra energía y puertas y todo eso buen material. En estos días harías una especie de simulador, tengo entendido que ARM fue un simulador de software primero y luego los diseños de hardware llegaron más tarde, no sé si eso es cierto, pero se apega a esa historia. Esto depende del equipo, algunos equipos pueden ser solo personas de hardware y solo quieren ingresar a la programación en el HDL, algunos como yo pueden querer hacer un poco de ambos. En la actualidad, existen buenos simuladores de lenguaje de hardware para que no tenga que construir ningún hardware que compile y simule, y realice gran parte de su depuración con un programa / paquete de simulación de hardware. el equipo de software puede desarrollar ensambladores y compiladores para el conjunto de instrucciones y usar programas de alimentación simulada de ram y rom para el procesador simulado y ponerlo a prueba. hemos simulado un arranque completo de Linux en un procesador en el que trabajé no hace mucho tiempo, tomó muchas horas pero funcionó (de esa manera encontré un error de caché en la lógica).

Así que ahora por lo que realmente creo que estabas preguntando. ¿Cómo se pasa de puertas básicas a un procesador con un conjunto de instrucciones? Bueno, las compuertas básicas AND, OR, NOT son realmente analógicas, no tienen un concepto de tiempo, no puede cambiar instantáneamente el voltaje en las entradas y, a medida que cambia ese voltaje, las salidas comienzan a cambiar. las compuertas están hechas de transistores y los transistores son amplificadores, tome la entrada multiplíquela por algún número y permita que fluya tanta corriente por el otro lado. Cuando los usamos como puertas lógicas, en realidad los estamos saturando en exceso, el voltaje de entrada es tan alto o bajo que el transistor solo puede conducir con voltaje máximo o sin voltaje (corriente). Básicamente, el transitor se convierte en un interruptor. larga historia corta, no hay concepto de tiempo. Para tener un conjunto de instrucciones, tenemos que tener instrucciones para poder secuenciar a través del programa, tenemos que tener un concepto de ahora que estamos en esta instrucción, y en el próximo intervalo de tiempo trabajaremos en esa instrucción. Al igual que el juego de convertir un amplificador en un interruptor, juegas juegos similares con el uso de puertas lógicas básicas con un reloj. los relojes provienen de cristales mágicos en una lata (no vale la pena meterlos aquí) que generan voltajes que se encienden y apagan a una velocidad fija. usa ese voltaje en ecuaciones lógicas y puedes comenzar a secuenciar cosas. los relojes provienen de cristales mágicos en una lata (no vale la pena meterlos aquí) que generan voltajes que se encienden y apagan a una velocidad fija. usa ese voltaje en ecuaciones lógicas y puedes comenzar a secuenciar cosas. los relojes provienen de cristales mágicos en una lata (no vale la pena meterlos aquí) que generan voltajes que se encienden y apagan a una velocidad fija. usa ese voltaje en ecuaciones lógicas y puedes comenzar a secuenciar cosas.

Piense muy brevemente en esta tabla de verdad:

0 0 0
0 1 1
1 0 1
1 1 0

en binario:

0 + 0 = 1
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10 (2 decimal)

centrándose solo en lsbit, un sumador de un bit, la tabla de verdad anterior describe un sumador de un bit. También describe una puerta XOR. Una entrada es verdadera o la otra pero no ambas.

Para obtener más de un bit, debe mirar los bits de acarreo llevar y llevar a cabo y necesita un sumador de tres bits, dos operandos y un acarreo con dos salidas, llevar a cabo y el bit de resultado. Una vez que tenga ese sumador de tres entradas y dos salidas, puede conectarlo en cascada tan ancho como desee. Pero esto sigue siendo analógico, las puertas cambian instantáneamente.

La forma en que convierte este sumador analógico en una instrucción ADD es que tiene cierta lógica que analiza la instrucción que se encuentra como entradas a estas puertas que ha organizado. algunos de los bits en la instrucción dicen, esta es una instrucción de agregar, algunos de los bits dicen que un operando es tal y tal registro, tal vez el registro 7, otros bits pueden decir que el otro operando es el registro 4. y dependiendo de la arquitectura podría tener otro registro definido en la instrucción que dice poner el resultado en el registro 2. Ahora más lógica ve esto, ya que necesito registrar el contenido de 7 para enrutarlo a una entrada del sumador alu y registrar las entradas de 4 enrutadas al sumador, y usted enruta la salida del sumador para registrar 2. Dado que el reloj es parte de esta lógica, hay un período de tiempo desde el comienzo del período de reloj hasta el comienzo del siguiente período de reloj donde todas las señales analógicas se establecen y resuelven la ecuación lógica para la que están conectadas. No muy diferente de cuando enciende un interruptor de luz, cambia el estado de las luces de decir apagado a encendido. La luz tarda un período de tiempo en calentarse y, básicamente, entrar en un estado estable. No muy diferente aquí.

Hay cierta lógica que dice cosas como si este período de reloj es la fase de ejecución de una instrucción AND, luego, en el siguiente período de reloj, voy a guardar el resultado en el registro de salida. al mismo tiempo voy a buscar la siguiente instrucción, etc. Entonces, para los procesadores modernos donde la ejecución de alu es a menudo solo un período de reloj porque la lógica analógica puede resolver las ecuaciones lógicas tan rápido. Los procesadores más antiguos que tenía que contar hasta cierto número dejan el sumador conectado, esperan x número de ciclos de reloj para que se resuelva la lógica del sumador, luego muestrean el resultado de la salida, alimentan las diferentes entradas de aluminio, esperan x número de ciclos de reloj para que para resolver, repita para siempre o hasta que se apague

¿Qué quiero decir con ecuaciones lógicas? solo eso, si quieres puedes pensar en términos de AND, OR, NO puertas. Para cada bit de entrada al circuito sumador alu hay una ecuación, probablemente una ecuación muy larga que incluye el reloj, que incluye los flip flops (bits de memoria individuales / individuales) que contienen la instrucción actual (más las ecuaciones que alimentan cada uno de esos bits de memoria) y así sucesivamente. Tome una sola función de software que haya escrito, en el idioma que la haya escrito, suponiendo que esta sea una función que toma las entradas, realiza una tarea y luego finaliza y devuelve un resultado. Piense en todas las combinaciones posibles de entradas y cuáles son las diferentes rutas de ejecución a través de esa función. Es posible que lo haya escrito en algún lenguaje de alto nivel, pero probablemente podría incluso reescribirlo en ese idioma para que sea más primitivo y más primitivo utilizando muchas estructuras anidadas if-then-else. e ir más abajo al lenguaje ensamblador quizás. No muy diferente de las ecuaciones de las que estoy hablando, el programador de hardware no programa en estas ecuaciones de largo aliento más de lo que probablemente programe en árboles de largo aliento si-entonces-otro en lenguaje ensamblador cuando el lenguaje de programación elegido ahorra mucho de eso. Al igual que el compilador que usa convierte su pequeño código fuente en un ensamblaje de largo aliento con muchos if-then-elses, hay un compilador que toma el código del lenguaje de programación de hardware y lo convierte en ecuaciones lógicas.

Ahora volviendo a la primera CPU (que hoy consideraríamos un microcontrolador pero luego fue una CPU). Hiciste todo lo anterior en papel, y no usaste lenguajes de programación de hardware, en realidad escribiste las ecuaciones lógicas, pero elegiste aún más cuidadosamente los patrones de bits para las instrucciones para hacer que el número de puertas y los cables para conectar esas puertas sean simples tan práctico En papel, a mano tenía que crear la larga lista de puertas lógicas cableadas y luego tenía que dibujar los componentes reales en una versión ampliada de la máscara de silicio. incluso hoy en día, los chips se hacen usando lo que es similar a un proceso fotográfico o de serigrafía en términos simples, por lo que tomaría estos planos si lo desea y los encogerá para luego aplicarlos a las capas de silicio.

aquí de nuevo en el pasado, todos tenían un mejor manejo del ensamblaje y no solo podría terminar haciendo una programación de ensamblaje, es posible que no haya tenido un editor de texto ni un ensamblador, es posible que haya tenido que escribir sus primeros programas a mano en papel, luego usando un manual de referencia, convertido a mano en código máquina, unos y ceros. En algunas de esas computadoras, es posible que haya tenido que cargar el ram accionando interruptores, volteando los bits de dirección, volteando los bits de datos hasta que coincidan con los números en su papel, voltee el bit del reloj hacia arriba y luego hacia abajo y haya cargado una ubicación de memoria con un byte de una instrucción de su programa, repita cientos de veces más y espero no cometer errores.

De la misma manera que el primer compilador de C, digamos, probablemente se escribió en algún otro idioma, luego se convirtió en autohospedaje al ser reescrito en C y compilado por el primer compilador de C nuevamente. Luego, los compiladores de C se usaron para inventar otros lenguajes de programación que luego se convirtieron en autohospedaje. Inventamos sistemas operativos y editores de texto que se construyeron sobre sí mismos, y todo es magia negra que dejan algunas personas detrás de la cortina en la esquina para hacer ...

Sí, muy largo aliento, es una gran pregunta que necesita años de estudio y experiencia para comprender realmente. mira mi lsasim, no pretendo ser un experto en nada, pero es un conjunto de instrucciones, hay un simulador que ejecuta la instrucción escrita en C y otra implementación del procesador implementado en un lenguaje de programación de hardware que puede ser simulado usando diferentes herramientas. Además de un ensamblador crudo y algunas otras herramientas y tal. Quizás, al examinar algo de esto, en particular el código del lenguaje de programación de hardware, podría cerrar la brecha en lo que supongo que estaba preguntando. Si no he cerrado esa brecha o he hecho una tangente larga sin aliento, avíseme si eliminaré esta respuesta (suponiendo que sea capaz de no pasar mucho tiempo en el intercambio de programadores).

viejo contador de tiempo
fuente
Esto realmente no responde la pregunta del autor, al menos no agrega nada a la discusión, que la respuesta aceptada no cubrió. Su matemática binaria no es 100% correcta 1 + 1 es 0 con un desbordamiento de 1. Dependiendo del tamaño del registro, sería 2 o 0.
Ramhound
@dwelch ¡MALDITA! Soy tu fanático del corazón si nada menos. +1
AceofSpades
2

Las CPU funcionan en 0 y 1. Todas las instrucciones tenían una secuencia de bits que las definía. Este era el código de la máquina. Es difícil para los humanos leer y escribir. Como primer paso, agrupamos los 0 y 1 en secuencias de 4 bits y usamos 0 a F para representarlos. Esto redujo los números que teníamos que memorizar, pero aún así no fue fácil recordar el código hexadecimal para las instrucciones.

Así que comenzamos a usar el ensamblaje que tenía "palabras" como MOV y ADD. El ensamblador reemplazaría las instrucciones con el conjunto correcto de 0 'y 1 convirtiendo la "lista" de ensamblaje a código de máquina.

Finalmente, desarrollamos lenguajes de "nivel superior" donde las "instrucciones" podrían representar secuencias enteras de código de máquina.

Jim C
fuente
Para su información, octal se utilizó como taquigrafía binaria antes que hexadecimal.
ocodo
Slomojo tiene razón, Octal, la base 8 usó 3 bits, se usó junto con el hexadecimal, la base 16 usó 4 bits. Octal tenía la ventaja de que todos sabían qué representaban los números del 0 al 7. La gente que no usaba Hex a menudo estaba desconcertada por los "dígitos" A a F.
Jim C
0

Recientemente me encontré con este Q / A y hace aproximadamente un año cuando comencé a recorrer este camino; Habría encontrado que este es un muy buen recurso y una página de referencia con respecto a mis propias preguntas relacionadas.


Parte 1: -Prefacio-

Un poco sobre mi:

A mediados y finales de los 80, cuando todavía estaba en la escuela primaria, desarmaba equipos de música basura, videograbadoras y otros dispositivos electrónicos que eran de los años 50 a los 80 y miraba las placas de circuitos y siempre quería saber cómo funcionaban. trabajo ... ¿Cómo adquirieron realmente la señal de transmisión, produjeron audio, video, hicieron esto y aquello, etc.? Podía reconocer las partes individuales aquí y allá, como una resistencia, un condensador, un diodo y un transistor, pero no lo hice. saber qué hicieron o cómo funcionaron a una edad tan temprana.

A lo largo de los años, siempre he sido excepcional en Matemáticas, Física y Química. Entendí las matemáticas en un alto grado e incluso pude leer algunos circuitos simples o básicos de mis días de secundaria y preparatoria que vinieron después, pero nunca llegué a aprender sobre las puertas lógicas y cómo se construyeron ... Sin embargo, lo hice aprender álgebra booleana en la escuela secundaria de mi clase de honores de lógica, probabilidad y estadística. Todas mis clases de matemáticas y ciencias fueron clases de honor. No tomé Cálculo hasta mi segundo semestre en un colegio comunitario. Hice una prueba de álgebra universitaria y tomé la trigonometría como un curso de actualización. Mi nivel más alto de matemáticas en el aula es el cálculo II de una sola variable.

He estado jugando videojuegos desde que tenía 3 o 4 años. Cuando era niño tuve el Atari, el NES, Sega Genesis y la PS1. A medida que crecía y llegaba a los últimos años de mi adolescencia y principios de los 20, adquirí la PS2 y la SNES con títulos seleccionados preferidos. ¡Esto tampoco tiene en cuenta los juegos de PC que se remontan a Doom!

Siempre he sido un ávido jugador de consolas y PC y esto no incluye juegos de pinball y arcade.

Me regalaron mi primera PC cuando tenía unos 12 años para Navidad a principios de los 90. Los días de DOS 6.0 y Win 3.11 o OS / 2. Desde entonces, siempre he estado familiarizado con la familia de sistemas operativos "Windows" y todos los sistemas que he tenido fueron Arquitectura Intel. He tenido una experiencia limitada con Apple o Mac en la escuela o la universidad, pero nunca tuve el privilegio de trabajar en sistemas Linux. Tengo Cygwin y he intentado aprender bash, pero estoy tan acostumbrado a Dos o la sintaxis del símbolo del sistema.

A principios de los 90 recibía una o dos copias de PC-World y escribía los fragmentos de código en QBasic, que no conocía muy bien e intentaba hacer que esos programas funcionaran. El único que tuvo éxito fue un programa para convertir las pulsaciones de teclas en la fila de teclas de inicio en diferentes tonos de llamada. No me refiero a los tonos de llamada en un teléfono celular, me refiero a una frecuencia continua siempre que mantenga presionada la tecla.

Siempre ha sido una pasión mía no solo querer saber cómo funcionan los dispositivos electrónicos dentro del circuito a nivel digital y lógico, aprender a programar una computadora, sino que siempre he tenido el deseo de querer hacer mi propio video juegos. Incluso a principios de los 90 quería hacer los juegos Frogger y Tetris ...


Esto se convirtió en mi principal motivación y deseo de abordar uno de los tipos más difíciles de desarrollo de programación o software dentro del campo de la informática y es el diseño de motores de juegos en 3D. Hay otros campos en Ciencias de la Computación que son igual de difíciles, sin embargo, cualquier motor de juego sofisticado generalmente o casi todos los incluirá, ya que los componentes individuales o submotores requieren sus técnicas y / o propiedades.

Tenía algo de experiencia en programación desde mis días de escuela secundaria, pero esto se limitó al horrible Visual Basic. Comencé a aprender y aprender C / C ++ alrededor de 2002 - 2003 no hasta unos años después de graduarme de la escuela secundaria en 1999. Incluso hasta el día de hoy no tengo ninguna experiencia de clase universitaria en Ciencias de la Computación o Ingeniería en Computación, sino a través de dedicación y determinación, he aprendido casi todos los conceptos que existen cuando se trata de computadoras, hardware, programación, algoritmos, etc. y aún sigo aprendiendo todo lo que puedo ...

Durante los primeros días de aprendizaje de C / C ++, tuve acceso a Internet, pero Internet estaba en sus primeras etapas, sitios web como Amazon, Youtube, Facebook, etc., aún no existían, todavía eran los días de 56k módems de acceso telefónico que aumentan su línea telefónica si no tuviera una segunda línea dedicada. Tomaría unos minutos para que una imagen se muestre en la pantalla, sin importar la reproducción continua de video.

Entonces, cuando se trataba de investigar y aprender a programar en C ++, los recursos eran limitados y la mayoría estaban en formato de texto. Al intentar abordar los proyectos de los primeros días de tutoría en Internet, muchos de esos proyectos no estaban completamente completos, los escritores eran profesionales o estudiantes universitarios e hicieron muchas suposiciones de que el lector ya estaba familiarizado con muchos de los conceptos necesarios, como la compilación , vinculación y depuración e integración de bibliotecas.

Para alguien que no sabe nada sobre esos temas, está perdido porque no sabe qué salió mal, ni cómo solucionarlo y cómo hacer que funcione correctamente. Me llevó muchas horas de prueba y error en esos días con recursos muy limitados. ¡Pedir ayuda como podemos ahora con este sitio web o buscar explicaciones detalladas que pueda encontrar en cppreference no estaba disponible! Si personalmente no conocía a nadie, ¡no había tantos a los que pudiera recurrir para obtener ayuda!

A medida que pasó el tiempo, mejoré algunos de mis conocimientos aquí y allá, y finalmente Internet mejoró a DSL, y ahora Internet de alta velocidad, los sitios web se volvieron más interactivos, los videos comenzaron a aparecer, la calidad de los videos mejoró con el tiempo, sitios como a medida que Youtube comenzó a aparecer y las cosas se volvieron un poco más fáciles en el lado de la investigación. Más y más tutoriales estuvieron disponibles, algunos eran buenos y útiles, mientras que otros enseñaban malas prácticas ...

También pasé mucho tiempo buscando y adquiriendo las herramientas necesarias para el desarrollo. Tuve que aprender la sintaxis del lenguaje, el compilador y el proceso de compilación, vinculación, construcción y depuración. Luego tuve que aprender sobre las diferentes bibliotecas y API disponibles que hay y cómo configurar mis proyectos o soluciones para vincular todas esas dependencias.

A lo largo de los años, he visto crecer, evolucionar y adaptarse el lenguaje C ++ con el tiempo. Al principio se mantuvo casi igual durante muchos años, pero en los últimos 10 años ha cambiado drásticamente en este corto lapso desde su inicio.

Menciono todo esto porque C ++ es uno de los lenguajes más difíciles de dominar por completo debido a su versatilidad, potencia, rico conjunto de características y la capacidad de permitirte dispararte en el pie. E incluso con todas sus advertencias, es uno de los lenguajes más potentes y preferidos que se utiliza en la industria líder como estándar para este tipo de desarrollo porque, cuando se hace correctamente, es rápido, conciso, confiable y utiliza el huella de pie más pequeña.

Desde entonces, he sido autodidacta en C / C ++ durante muchos años con la intención y el enfoque en aprender programación de gráficos 3D y diseño de motores de juegos. He dedicado de 100 a 1,000 horas de búsqueda, investigación y mucho más en lectura, aprendizaje y aplicación de ese conocimiento en el diseño de productos y aplicaciones de trabajo útiles. Siempre he tenido la voluntad y el deseo de querer aprender más para mejorar mis habilidades y habilidades.


Esta fue la primera etapa, luego comencé a leer y trabajar inicialmente con DirectX 9.c, lo que hice en C / C ++ e incluso C #. Luego me mudé a DirectX 10 y Legacy OpenGL 1.0. De ellos vinieron DirectX 11 y OpenGL 3.x - 4.xy ahora incluso he probado suerte en Vulkan.

He creado motores de juegos exitosos trabajando a través de varios tutoriales en línea, tanto en formato de texto como de video. Ya dije que tenía una sólida formación en matemáticas, pero se limitaba al cálculo I y II. Tuve que enseñarme a mí mismo Cálculo vectorial del que tenía conocimiento de mi clase de Física basada en Cálculo en la universidad, pero en cuanto a Álgebra lineal con transformaciones afines y geometría analítica, tuve que aprenderlos por mi cuenta cuando ciertas ecuaciones, funciones, métodos, algoritmos y Se necesitaban conceptos. Luego tuve que aprender a traducirlos en un código eficiente, legible, confiable y reutilizable que fuera genérico y libre de errores lo más posible, lo que supondría cientos de miles de horas de depuración.

Ha sido un viaje maravilloso aprender los temas y algoritmos que incluyen administración de memoria, conteo de referencias, creación de instancias, recursión y mucho más que se utilizan en muchos, si no en todos, los componentes de un motor de juego donde son vastos. Podría enumerarlos todos aquí, pero eso sería suficiente información para llenar 3 o 4 espacios de respuesta por escrito. Sin embargo, incluiré la lista de temas generales, pero no sus subtemas.

Aquí están los temas o la lista de temas en lo que consiste en un motor de juego completamente funcional que incluye todas las diversas técnicas de desgarrado, configuración de las tuberías de renderizado y sombreado, técnicas de sombreado e iluminación a través de sombreadores, procesamiento previo y posterior, amortiguadores de cuadros, amortiguadores posteriores , carga de imágenes, carga y análisis de audio y modelos, creación de formas primitivas con propiedades de material de color, textura y coordenadas normales con mapeo manual de texturas, transformaciones de objetos, tipos de cámara, jerarquías de gráficos de escena, clases de administrador para texturas, audio, fuentes y sombreadores y gestión de memoria, sistema de registro con manejo de excepciones, técnicas de programación de subprocesos múltiples y paralelos, redes, motor de física, detección de colisión, generador de partículas, animación, IA del juego, generación de terreno, cajas de cielo y domos de cielo, representación de agua,follaje y más ..., GUI con fuente texturizada para la representación de texto, superposiciones de HUD, inventarios, generación de mapas y macros, sistema de estado y máquinas de estado, y finalmente escribir un analizador para crear su propio lenguaje de secuencias de comandos para automatizar gran parte de estos objetos. la capacidad de cambiar los valores de datos dentro del motor sin tener que volver a compilar simplemente cargando los archivos de datos para llenar los objetos y estructuras de datos dentro de sus respectivos contenedores al inicio de la aplicación.y finalmente escribir un analizador para crear su propio lenguaje de secuencias de comandos para automatizar gran parte de estos objetos para tener la capacidad de cambiar los valores de datos dentro del motor sin tener que volver a compilar simplemente cargando los archivos de datos para llenar los objetos y estructuras de datos dentro de sus respectivos contenedores al inicio de la aplicación.y finalmente escribir un analizador para crear su propio lenguaje de secuencias de comandos para automatizar gran parte de estos objetos para tener la capacidad de cambiar los valores de datos dentro del motor sin tener que volver a compilar simplemente cargando los archivos de datos para llenar los objetos y estructuras de datos dentro de sus respectivos contenedores al inicio de la aplicación.


A lo largo de los años, me ha intrigado querer aprender lenguaje ensamblador, de ellos quería aprender sobre compiladores, ensambladores y sistemas operativos simples, me refiero a su funcionamiento interno, cómo se construyen y diseñan.

Pasó el tiempo y luego me aparté un poco y comencé a aprender a emular hardware. Me centré específicamente en el NES pero quería aprender la emulación de hardware de las CPU en general. Esto me llevó a aprender sobre el conjunto de instrucciones en el que ya conocía el concepto y lo que era, ya que estaba familiarizado con la familia x86 de Intel hasta cierto punto, pero ahora tenía que aprender el Conjunto de instrucciones 6502.

Sin embargo, al sumergirme en esto, terminé investigando más y comencé a aprender sobre la arquitectura del conjunto de instrucciones desde una perspectiva de ingeniería. Esto me llevó a aprender sobre cómo se construye la CPU a partir de las puertas lógicas y cómo se construyen las puertas lógicas a partir de los transistores junto con otros diversos componentes eléctricos. Así que terminé aprendiendo sobre esto desde dos perspectivas de arriba hacia abajo y de abajo hacia arriba. Ambos métodos fueron muy efectivos y creo que aprender de ambos ayuda a construir ese puente o brecha donde el software se une al hardware.

A partir de esto, tuve que actualizar mi Álgebra booleana y terminé aprendiendo sobre K-Maps, Tablas de implicación, Máquinas de estado tanto Mealy como Moore y varias otras cosas que relacionan la lógica binaria y la aritmética con las puertas lógicas físicas y los circuitos integrados. Y esto me lleva al pasado resentido donde comencé a trabajar con Logisim y comencé a aprender HDL, VHDL, Verilog, etc.

He estado aprendiendo todo esto en mi tiempo libre cuando pude durante los últimos 15-18 años.


Estos son algunos de los sitios y enlaces que me han guiado a lo largo de los años. Muchos de estos son recientes, ya que muchos de los sitios de los que aprendí originalmente ya no existen, he perdido sus enlaces y no recuerdo, o los motores de búsqueda los empujaron al final de sus listas de búsqueda ...

  • Lenguajes - C ++

  • Tutoriales de gráficos 3D y sitios web de recursos

  • Las series y canales de Youtube cubren los temas anteriores, así como hardware, informática e ingeniería eléctrica. Hay demasiados para enumerar, así que enumeraré algunos de ellos aquí que encuentro más útiles e ingeniosos. No proporcionaré los enlaces, pero puedes buscar en YouTube estos canales.

    • 3Blue1Brown - Matemáticas avanzadas
    • Bisqwit - Programación avanzada C / C ++ (Proyectos de aplicación) - Emulador de hardware NES
    • Jason Turner - Técnicas avanzadas de programación moderna en C ++
    • javidx9 - Programación avanzada C / C ++ (Proyectos de aplicación) - Emulador de hardware NES / Algunos ensamblajes
    • MIT OpenCourse - Cursos universitarios en matemáticas y ciencias de la computación
    • Bilkent Online Courses - Cursos universitarios en informática e ingeniería informática (diseño de CPU MIPS)
    • The Cherno - Temas y aplicaciones avanzados de programación C / C ++ - Desarrollo de motores de juegos
    • Ben Eater - Ingeniería de hardware - Aplicación práctica a través de paneles de pruebas
    • Neso Academy - Ingeniería de hardware - Teoría y conceptos
    • Socratica - Programación en Python
    • En pocas palabras - Ingeniería de hardware - Teoría y conceptos
    • Bitwise - C / C ++ avanzado Diseño de un ensamblador mediante emulación de hardware
    • Bo Qian - C ++ Temas en estructuras de datos y algoritmos.
    • LineByLine - Programación Vulkan
    • Joshua Shucker - Programación Vulkan
    • www.MarekKnows.com - C ++, Matemáticas 3D y Desarrollo de motores de juegos

Y estos no tienen en cuenta algunos de los varios libros que tengo sobre estos temas.

-Nota- Por favor no vote sobre esto, ya que este es solo un mensaje para el lector de mi propia experiencia personal y no tiene ningún intento de responder o hacer referencia a la pregunta original. En los próximos días cuando tenga tiempo; Agregaré una respuesta de seguimiento para dar mi opinión sobre la pregunta del OP mientras proporciono enlaces útiles como referencia y conjunto de recursos y actualizaré esta respuesta también para incluir algunos enlaces aquí y modificar esta nota. Es tarde y actualmente no tengo tiempo para revisar y editar lo que ya he escrito. Lo haré cuando pueda ".

Francis Cugler
fuente
Acabo de actualizar esta respuesta o publicación. Iba a agregar la segunda parte que realmente respondería la pregunta, sin embargo, no tengo suficientes puntos de reputación para hacerlo. Me llevará algo de tiempo acumular los puntos de reputación necesarios antes de poder agregar mi segunda respuesta. Esta publicación no es la respuesta real, pero la usaré como referencia y buscaré en la tabla el razonamiento de mi respuesta verdadera. Es necesario tener algunos de los recursos enumerados anteriormente para ayudar a cerrar la brecha entre el software y el hardware.
Francis Cugler
-2

En esencia, una CPU generalmente es solo una máquina de estado. Por lo tanto, deberá comprender cómo las puertas lógicas y las chanclas o registros se combinan para hacer máquinas de estados.

Una máquina de estado toma entradas y el estado actual, los ejecuta a través de lógica booleana (y potencialmente aritmética), y luego proporciona salidas y un estado siguiente. Una de las entradas puede ser el registro de instrucciones. Una de las salidas puede ser una habilitación y una selección para que la fuente vuelva a cargar el registro de instrucciones, quizás también incremente o cargue otro registro que actúe como un contador de programa. Con eso, además de un poco de memoria direccionable, puede secuenciar a través de instrucciones.

Una vez que tenga una forma de secuenciar las instrucciones, puede usar la lógica para decodificar estos bits de instrucciones, más el estado actual, en otro grupo de bits de control. Algunos de estos bits de control pueden actuar como entradas para controlar un montón de lógica que puede hacer lógica aritmética y de toda la palabra, llámela ALU. Otros bits pueden cargar cosas o seleccionar entradas para la ALU. Otros bits pueden decir dónde almacenar los resultados de la ALU. O cargar registros de direccionamiento. O escriba en la memoria u otras salidas. Etc.

Parte del diseño de un conjunto de instrucciones es descubrir qué combinaciones de bits, cuando se decodifican, controlan todos los registros y la secuencia de la máquina de estados. Esto se había hecho y (re) optimizado miles de formas diferentes.

Hay al menos 3 niveles de libros de texto universitarios sobre este tema no trivial.

hotpaw2
fuente
2
Esto no explica cómo la operación MOV se convierte en valor binario. Esto no menciona que la operación MOV de instrucción es un valor, es una palabra clave que usamos, por lo que no tenemos que memorizar un valor binario de 16 a 32 bits.
Ramhound