¿Se escribieron los primeros ensambladores en código máquina?

42

Estoy leyendo el libro The Elements of Computing Systems: Building a Modern Computer from First Principles , que contiene proyectos que abarcan la construcción de una computadora desde puertas booleanas hasta aplicaciones de alto nivel (en ese orden). El proyecto actual en el que estoy trabajando es escribir un ensamblador usando un lenguaje de alto nivel de mi elección, para traducir del código de ensamblaje de Hack al código de máquina de Hack (Hack es el nombre de la plataforma de hardware construida en los capítulos anteriores). Aunque todo el hardware se ha construido en un simulador, he tratado de fingir que realmente estoy construyendo cada nivel usando solo las herramientas disponibles para mí en ese punto del proceso real.

Dicho eso, me hizo pensar. Usar un lenguaje de alto nivel para escribir mi ensamblador es ciertamente conveniente, pero para el primer ensamblador escrito (es decir, en la historia), ¿no necesitaría estar escrito en código de máquina, ya que eso era todo lo que existía en ese momento?

Y una pregunta correlacionada ... ¿qué tal hoy? Si sale una nueva arquitectura de CPU, con un nuevo conjunto de instrucciones y una nueva sintaxis de ensamblaje, ¿cómo se construiría el ensamblador? Supongo que aún podría usar un lenguaje de alto nivel existente para generar binarios para el programa ensamblador, ya que si conoce la sintaxis de los lenguajes ensamblador y de máquina para su nueva plataforma, entonces la tarea de escribir el ensamblador es realmente solo una tarea de análisis de texto y no está inherentemente relacionada con esa plataforma (es decir, necesita ser escrita en el lenguaje de máquina de esa plataforma) ... esa es la razón por la que puedo "engañar" mientras escribo mi ensamblador Hack en 2012, y utilizo algunos preexistentes lenguaje de alto nivel para ayudarme.

El111
fuente
17
Siempre puede escribir un compilador cruzado y usarlo para producir un código para nuevo hardware hoy en día.
Kerrek SB
@PersonalNexus Gracias por eso, snafu edit de mi parte.
Yannis
1
@YannisRizos No hay problema, nos pasa a los mejores :)
PersonalNexus
8
Es posible que el primer ensamblador haya sido escrito en conjunto en una hoja de papel. La conversión al código de máquina podría haberse realizado todavía en papel y grabada en algún tipo de ROM con interruptores, una palabra a la vez.
mouviciel
Mi primera computadora fue una ZX81, con 1 KB de RAM, por lo que mis programas de código de máquina (ciertamente cortos) de hecho fueron traducidos a mano.
usuario281377

Respuestas:

37

para el primer ensamblador que se haya escrito (es decir, en la historia), ¿no sería necesario escribirlo en código máquina?

No necesariamente. Por supuesto, la primera versión v0.00 del ensamblador debe haber sido escrita en código máquina, pero no sería lo suficientemente potente como para llamarse ensamblador. No admitiría ni siquiera la mitad de las características de un ensamblador "real", pero sería suficiente para escribir la próxima versión de sí mismo. Luego, podría volver a escribir v0.00 en el subconjunto del lenguaje ensamblador, llamarlo v0.01, usarlo para construir el siguiente conjunto de características de su ensamblador v0.02, luego usar v0.02 para construir v0.03, y etc., hasta llegar a v1.00. Como resultado, solo la primera versión estará en código máquina; la primera versión lanzada estará en lenguaje ensamblador.

He desarrollado un programa de compilación de lenguaje de plantillas usando este truco. Mi versión inicial estaba usando printfdeclaraciones, pero la primera versión que utilicé en mi compañía estaba usando el procesador de plantillas que estaba procesando. La fase de arranque duró menos de cuatro horas: tan pronto como mi procesador pudo producir resultados apenas útiles, lo reescribí en su propio idioma, compilé y tiré la versión sin plantilla.

dasblinkenlight
fuente
44
¿Aún tienes todas las fases? Me encantaría verlos y compararlos entre sí. Solo para tener una idea del proceso que atravesó.
Marjan Venema
3
@MarjanVenema No, ya no los tengo, lo construí en 1998 y seguí usándolo hasta 2005, cuando descubrí StringTemplate . Estaba sobrescribiendo la fase anterior con la siguiente mientras trabajaba hacia la versión inicial utilizable. Mi ciclo de desarrollo consistió en codificar cosas nuevas, ejecutar el generador de código para construirlo en un directorio separado, ejecutar diffcontra el generador de código actual para ver que la porción generada del código no cambiaba de manera inesperada, reemplazar el código en su lugar, y ejecutándolo una vez más para terminar el ciclo.
dasblinkenlight
Lástima pero comprensible :) Gracias por describir lo que hiciste (y por el enlace).
Marjan Venema el
3
Creo que necesitas mantener una especie de cadena de arranque. Código de máquina => ASM limitado => ASM completo => Algún idioma. De lo contrario, si pierdes tu binario en cualquier paso del camino, te atornillarán. (Alternativamente, podría tener una versión de compilación cruzada en C, ya que de manera realista no todos los binarios del compilador en C desaparecerán de una vez.)
edA-qa mort-ora-y
3
Las únicas "características" que un ensamblador necesita para ser un ensamblador "real" es ensamblar.
Miles Rout
23

Según Wikipedia, Nathaniel Rochester implementó el primer lenguaje ensamblador / ensamblador para IBM 701 . (Las fechas son un poco inciertas en el artículo de Wikipedia. Establece que Rochester se unió a IBM en 1948, pero otra página de Wikipedia dice que el 701 se anunció públicamente en 1952. Y esta página de IBM afirma que "[el diseño actual comenzó en febrero 1, 1951 y se completó un año después " .)

Sin embargo, "Ensambladores y cargadores" de David Salomon afirma (en la página 7) que EDSAC también tenía un ensamblador:

"Una de las primeras computadoras del programa almacenado fue la EDSAC (Calculadora automática de almacenamiento electrónico de retardo) desarrollada en la Universidad de Cambridge en 1949 por Maurice Wilkes y W. Renwick. Desde sus primeros días, la EDSAC tuvo un ensamblador, llamado Órdenes iniciales. Fue implementado en una memoria de solo lectura formada por un conjunto de selectores telefónicos rotativos, y aceptaba instrucciones simbólicas. Cada instrucción consistía en un mnemónico de una letra, una dirección decimal y un tercer campo que era una letra. El tercer campo causaba uno de 12 constantes preestablecidas por el programador para ser agregadas a la dirección en el momento del montaje ". (Se omitieron las referencias ... ver el original).

Suponiendo que aceptamos que "Órdenes iniciales" tiene prioridad, tenemos evidencia clara de que el primer ensamblador se implementó en código máquina.

Este patrón (escribir los ensambladores iniciales en código de máquina) habría sido la norma en la década de 1950. Sin embargo, de acuerdo con Wikipedia , "[a] ssemblers fueron las primeras herramientas de lenguaje para iniciarse". Consulte también esta sección que explica cómo se utilizó un ensamblador primordial escrito con código de máquina para arrancar un ensamblador más avanzado que estaba codificado en lenguaje ensamblador.

En la actualidad, los ensambladores y compiladores están escritos en lenguajes de nivel superior, y un ensamblador o compilador para una nueva arquitectura de máquina generalmente se desarrolla en una arquitectura diferente y se compila de forma cruzada.

(FWIW: escribir y depurar programas no triviales en código máquina es un proceso extremadamente laborioso. Alguien que desarrolle un ensamblador en código máquina probablemente arrancaría a un ensamblador escrito en ensamblador lo antes posible).

Vale la pena leer esta página de Wikipedia sobre compiladores y ensambladores de arranque ... si esto es desconcertante para usted.

Stephen C
fuente
Votado por responder realmente en lugar de solo adivinar. ¡Esta lectura es realmente interesante!
JacquesB
14

Supongo que los primeros ensambladores se escribieron en código máquina, porque como usted dice, no había nada más disponible en ese momento.

Hoy, sin embargo, cuando sale una nueva arquitectura de CPU, usamos lo que se conoce como un compilador cruzado , que es un compilador que produce código de máquina no para la arquitectura en la que se está ejecutando, sino para una arquitectura diferente.

(De hecho, como estoy seguro de que descubrirá más adelante en el libro que está leyendo, no hay absolutamente nada que haga que un compilador sea inherentemente más adecuado para producir código de máquina para la arquitectura en la que se está ejecutando que en cualquier otro otra arquitectura. Es solo una cuestión de a qué arquitectura se dirigirá usted, como creador del compilador).

Por lo tanto, hoy es incluso posible (al menos en teoría) crear una arquitectura completamente nueva y tener compiladores de lenguaje de alto nivel que se ejecuten de forma nativa (compilados en otras arquitecturas que usan compiladores cruzados) incluso antes de tener un ensamblador para esa arquitectura.

Mike Nakis
fuente
12

Al principio, el "ensamblaje" se escribió en papel y luego se "compiló" manualmente en tarjetas perforadas.

Mi abuelo estaba trabajando con un ZRA1 (lo siento, la página solo existe en alemán, pero la traducción de Google está bien hasta el punto de que realmente puedes recoger los hechos más importantes: D).
El modus operandi era escribir su código en papel en una especie de lenguaje ensamblador y la secretaria realmente haría la transcripción a las tarjetas perforadas, luego las pasaría al operador y el resultado se devolvería la mañana siguiente.

Todo esto fue esencialmente antes de que los programadores tuvieran el lujo de ingresar datos a través de un teclado y verlos en una pantalla.

back2dos
fuente
3
Cuando estudiaba en la universidad, todavía tenían los bloques de papel utilizados para escribir el código de la máquina. Escribes el programa a la derecha, hay columnas a la izquierda para traducir las instrucciones al hexadecimal. Y una columna para la dirección actual. Los primeros ensambladores eran en realidad humanos.
Florian F
9

Es difícil estar seguro acerca de la muy primera ensamblador (difícil de definir, incluso lo que era). Hace años, cuando escribí algunos ensambladores para máquinas que carecían de ensambladores, todavía escribía el código en lenguaje ensamblador. Luego, después de tener una sección de código razonablemente completa, la traduje al código de la máquina a mano. Sin embargo, todavía eran dos fases completamente separadas: cuando estaba escribiendo el código, no estaba trabajando o pensando a nivel de código de máquina.

Debo agregar que en algunos casos, fui un paso más allá: escribí la mayor parte del código en un lenguaje ensamblador que encontré más fácil de usar, luego escribí un kernel pequeño (más o menos lo que ahora llamaríamos una máquina virtual) interpretar eso en el procesador de destino. Eso fue mortalmente lento (especialmente en un procesador de 1 MHz y 8 bits), pero eso no importó mucho, ya que normalmente solo se ejecutó una vez (o como máximo, algunas veces).

Jerry Coffin
fuente
8

No necesita un ensamblador para ensamblar a mano el código del lenguaje ensamblador en el código de la máquina. Del mismo modo que no necesita un editor para escribir código en lenguaje ensamblador.

Una perspectiva historica

Los primeros ensambladores probablemente fueron escritos en lenguaje ensamblador y luego ensamblados a mano en código máquina. Incluso si el procesador no tenía un 'lenguaje ensamblador' oficial, entonces los programadores probablemente hicieron la mayor parte del trabajo de programación utilizando algún tipo de pseudocódigo antes de traducir ese código a las instrucciones de la máquina.

Incluso en los primeros días de la informática , los programadores escribieron programas en una especie de notación simbólica y los tradujeron al código de la máquina antes de introducirlos en su computadora. En el caso de Augusta Ada King, ella habría necesitado traducirlos en tarjetas perforadas para el motor analítico de Babbage , pero desgraciadamente nunca se construyó.

Experiencia personal

La primera computadora que tuve fue una Sinclair ZX81 (Timex 1000 en los EE. UU.). La parte posterior del manual tenía toda la información que necesitaba para traducir Z80 lenguaje ensamblador en código máquina (incluso incluido, en todas las modo de índice extraños códigos de operación del Z80 tenía).

Escribiría un programa (en papel) en lenguaje ensamblador y ejecutaría el código en seco. Cuando estaba feliz de que mi programa no tuviera errores, buscaba cada instrucción en la parte posterior del manual, la traducía al código de la máquina y también escribía el código de la máquina en el papel. Finalmente, escribiría todas las instrucciones del código de máquina en mi ZX81 antes de guardarlo en cinta e intentar ejecutarlo.

Si no funcionaba, volvería a verificar el ensamblaje de mi mano y, si alguna traducción fuera incorrecta, parchearía los bytes cargados de la cinta antes de volver a guardarla e intentar nuevamente ejecutar el programa.

Por experiencia, puedo decirle que es mucho más fácil depurar su código si está escrito en lenguaje ensamblador que en código máquina, de ahí la popularidad de los desensambladores. Incluso si no tiene un ensamblador, el ensamblaje manual es menos propenso a errores que intentar escribir el código de la máquina directamente, aunque supongo que un programador real como Mel podría estar en desacuerdo. * 8 ')

Mark Booth
fuente
5

No hay diferencia entonces o ahora. Si quieres inventar un nuevo lenguaje de programación, eliges uno de los idiomas disponibles para crear el primer compilador. durante un período de tiempo, si es un objetivo del proyecto, crea un compilador en ese idioma y luego puede autohospedarse.

Si todo lo que tenía era lápiz y papel y algunos interruptores o tarjetas perforadas como interfaz de usuario para el primer o el siguiente conjunto de instrucciones nuevo, usted utilizó uno o todos los elementos disponibles para usted. Muy bien podría haber escrito un lenguaje ensamblador, en papel, y luego haber usado un ensamblador, usted, para convertirlo en código de máquina, tal vez en octal, y luego, en algún momento, que entró en la interfaz de la máquina.

Cuando se inventa hoy un nuevo conjunto de instrucciones, no es diferente, dependiendo de la compañía / individuos, prácticas, etc. (probablemente en hexadecimal o binario). Dependiendo del progreso de los equipos de software, pueden cambiar muy rápidamente o no durante mucho tiempo al lenguaje ensamblador y luego a un compilador.

Las primeras máquinas de cómputo no eran máquinas de uso general que se pudieran usar para crear ensambladores y compiladores. Los programó moviendo algunos cables entre la salida del alu anterior a la entrada del siguiente. Finalmente, tenía un procesador de uso general para poder escribir un ensamblador en ensamblaje, ensamblarlo a mano, alimentarlo como código de máquina, luego usarlo para analizar ebcdic, ascii, etc. y luego auto-host. almacene el binario en algún medio que luego pueda leer / cargar sin tener que mantener los interruptores activados al código de la máquina de alimentación manual.

Piense en tarjetas perforadas y cinta de papel. En lugar de accionar los interruptores, definitivamente podría hacer una máquina completamente mecánica, un dispositivo que ahorre trabajo, que creó los medios que leería la computadora. En lugar de tener que ingresar los bits del código de la máquina con interruptores como un altair, podría alimentar con cinta de papel o tarjetas perforadas (usando algo mecánico, no controlado por el procesador, que alimentó la memoria o el procesador, O usando un pequeño cargador de arranque escrito con código de máquina). Esta no era una mala idea porque podía hacer algo, impulsado por la computadora que también podía producir mecánicamente las cintas de papel o las tarjetas perforadas, y luego alimentarlas nuevamente. Dos fuentes de tarjetas perforadas, el dispositivo mecánico de ahorro de mano de obra no basado en computadora y la máquina impulsada por computadora. ambos producen los "binarios" para la computadora.

viejo contador de tiempo
fuente
1
+1 para el comentario "ensamblador, usted". Es fácil apegarse a una definición de una palabra (es decir, ensamblador = software), pero su comentario realmente pone de nuevo lo obvio en perspectiva ... que el "proceso de ensamblaje" es solo un sistema / rutina, uno que fácilmente podría ser llevado a cabo por Un ensamblador humano.
The111
1
También la gente se atasca en esta idea de que las primeras computadoras tenían conjuntos de instrucciones. Las primeras computadoras eran mujeres con buenas habilidades matemáticas con lápiz y papel, y así se llamaban computadoras. entonces esas mujeres (o una en particular) programaron el eniac conectando cables que no usan un conjunto de instrucciones. La programación con un conjunto de instrucciones fue bastante avanzada. Sí, es muy fácil quedar atrapado en el uso de una palabra o término como ensamblador o computadora o temprano.
old_timer
4

Hay una o dos instancias en el zoológico informático de Brook donde dijo algo así como "las mnemotécnicas son nuestro invento, el diseñador simplemente usó el código de operación numérico o el personaje cuyo código era el código de operación", por lo que había máquinas para las cuales ni siquiera había un lenguaje ensamblador.

Al ingresar a los programas, finalice la depuración en el panel frontal (para aquellos que no lo han hecho, era una forma de configurar la memoria, configurar algunos interruptores en la dirección, otros en el valor y presionar un botón u otro botón para leer el valor) fue común mucho más tarde. Algunos antiguos alardean de que aún podrían ingresar el código de arranque para las máquinas que usaron ampliamente.

La dificultad de escribir directamente el código de la máquina y leer programas del volcado de memoria depende bastante del lenguaje de la máquina, algunos de ellos son relativamente fáciles (la parte más difícil es rastrear las direcciones), x86 es uno de los peores.

Un programador
fuente
El pdp-11 ni siquiera tenía el lujo de las perillas. Puede alterar el almacenamiento ingresando la dirección binaria en 8 interruptores de palanca, y, el valor en 16 interruptores de palanca luego presione el botón. ¡En realidad vi a alguien arreglar un programa de bucle de esta manera!
James Anderson el
2

Construí una computadora en 1975. Era muy avanzada sobre su Altair contemporáneo, porque tenía una 'rom de monitor' que me permitía ingresar programas escribiendo el código de máquina en hexadecimal y viendo este código en un monitor de video, donde como con el En Altair, cada instrucción de máquina debía ingresarse poco a poco utilizando una fila de interruptores.

Entonces, sí, en los primeros días de las computadoras y luego nuevamente en los primeros días de las computadoras personales, las personas escribían aplicaciones en código de máquina.

Jim en Texas
fuente
2

Una anécdota:

Cuando aprendí el lenguaje ensamblador, en Apple] [, había un programa incluido en la ROM llamado micro ensamblador. Hizo una traducción inmediata de las instrucciones de ensamblaje a bytes, tal como las ingresó. Esto significa que no había etiquetas: si desea saltar o cargar, tenía que calcular las compensaciones usted mismo. Sin embargo, fue mucho más fácil que buscar los diseños de instrucciones e ingresar valores hexadecimales.

Sin duda, los ensambladores reales se escribieron primero usando el microensamblador, o algún otro entorno no completamente completo.

Sean McMillan
fuente