¿Cómo se hicieron los primeros compiladores?

69

Siempre me pregunto esto, y quizás necesito una buena lección de historia sobre lenguajes de programación. Pero como la mayoría de los compiladores de hoy en día se hacen en C, ¿cómo se hicieron los primeros compiladores (AKA antes de C) o se interpretaron todos los idiomas?

Dicho esto, todavía no entiendo cómo se hizo el primer lenguaje ensamblador, entiendo qué es el lenguaje ensamblador pero no veo cómo consiguieron que el primer lenguaje ensamblador funcionara (como, cómo lo hicieron). haz los primeros comandos (como mov R21 ) o w / e configuramos el equivalente binario?

    
pregunta gnat 30.06.2011 - 14:13

9 respuestas

88

Ha, he hecho esto. Muchas CPU tienen instrucciones simples de tamaño fijo que solo tienen un par de bytes. Por ejemplo, para una CPU simple como una Motorola 6800, podría encajar todas sus instrucciones en una hoja única de papel . Cada instrucción tendría asociado un código de operación de dos bytes y argumentos. Puede ensamblar a mano un programa buscando el código de operación de cada instrucción. Luego escribiría su programa en papel , anotando cada instrucción con su código de operación correspondiente. Una vez que haya escrito su programa, podría grabar cada código de operación en secuencia en una EPROM que luego almacenaría su programa. Conecte la EPROM a la CPU con las instrucciones correctas en las direcciones correctas y tendrá un programa de trabajo simple. Y para responder a tu siguiente pregunta, sí. Fue doloroso (lo hicimos en el instituto). Pero tengo que decir que el cableado de cada chip en una computadora de 8 bits y la escritura de un programa me dieron una comprensión profunda de la arquitectura de la computadora que probablemente no podría haber logrado de otra manera.

Los chips más avanzados (como x86) son mucho más difíciles de codificar a mano, porque a menudo tienen instrucciones de longitud variable. Los procesadores VLIW / EPIC como el Itanium son casi imposibles de codificar manualmente porque son Repartir en paquetes de instrucciones que son optimizados y ensamblados por compiladores avanzados. Para las nuevas arquitecturas, los programas casi siempre se escriben y ensamblan primero en otra computadora, luego se cargan en la nueva arquitectura. De hecho, para empresas como Intel que en realidad construyen CPU, pueden ejecutar programas reales en arquitecturas que aún no existen al ejecutarlos en simuladores. Pero estoy divagando ...

En cuanto a los compiladores, en su forma más simple, pueden ser poco más que programas de "cortar y pegar". Podría escribir un "lenguaje de alto nivel" muy simple, sin optimización, que simplemente agrupe las instrucciones simples en lenguaje ensamblador sin mucho esfuerzo.

Si desea un historial de compiladores y lenguajes de programación, le sugiero que obtenga un historial de FORTRAN .

    
respondido por el Dave Markle 30.06.2011 - 14:23
54

De eso se trata compilador bootstrapping (ya que nadie mencionó cómo se llama =).

  

el proceso de escritura de un compilador (o ensamblador) en el lenguaje de programación de destino que se pretende compilar. La aplicación de esta técnica lleva a un compilador de auto hospedaje.

     

Muchos compiladores para muchos lenguajes de programación son bootstrapped, incluyendo compiladores para BASIC, ALGOL, C, Pascal, PL / I, Factor, Haskell, Modula-2, Oberon, OCaml, Common Lisp, Scheme, Java, Python, Scala y más ...

     

El problema del huevo y la gallina

     

Si uno necesita un compilador para el lenguaje X para obtener un compilador para el lenguaje X (que está escrito en el lenguaje X), ¿cómo se escribió el primer compilador? Los posibles métodos para resolver este problema con la gallina o el huevo incluyen:

     
  • La implementación de un intérprete o compilador para el lenguaje X en el lenguaje Y. Niklaus Wirth informó que escribió el primer compilador de Pascal en Fortran.
  •   
  • Otro intérprete o compilador para X ya se ha escrito en otro idioma Y; esta es la forma en que Scheme a menudo se reinicia.
  •   
  • Las versiones anteriores del compilador se escribieron en un subconjunto de X para el que existía algún otro compilador; así es como se reinician algunos superseries de Java, Haskell y el compilador inicial de Free Pascal.
  •   
  • El compilador para X se compila de forma cruzada desde otra arquitectura donde existe un compilador para X; Así es como los compiladores para C se suelen portar a otras plataformas. También este es el método utilizado para Free Pascal después del arranque inicial.
  •   
  • escribiendo el compilador en X; luego, compírelo manualmente desde la fuente (lo más probable es que no esté optimizado) y ejecútelo en el código para obtener un compilador optimizado. Donald Knuth usó esto para su sistema de programación WEB alfabetizado ...
  •   
    
respondido por el vines 30.06.2011 - 15:59
15

En última instancia, todas las computadoras funcionan con códigos binarios, que se introducen en la CPU. Estos códigos binarios son perfectamente naturales para una CPU, pero también perfectamente inútiles para los seres humanos. Una de las primeras formas de escribir un programa fue perforando agujeros en las tarjetas. La posición de los orificios representó una posición de bit particular dentro de una palabra, y la presencia o ausencia del orificio se interpretó como un cero o uno. Estas tarjetas se colocaron en la secuencia correcta en una caja, y luego se introdujeron en un lector de tarjetas, que efectivamente las convirtió en código binario para la CPU (y su vida se perdería efectivamente si dejaba la caja).

Obviamente, los primeros programadores elaboraron los códigos binarios uno por uno y tenían una máquina para perforar las tarjetas. Esta es esencialmente la programación en lenguaje ensamblador en tus manos y rodillas. Una vez que tenga eso, puede crear todo lo demás a partir de él: un editor de texto simple, un compilador de lenguaje ensamblador (para convertir las declaraciones de ensamblaje de texto en códigos binarios), un enlazador y un cargador. Y el resto, como dicen, es historia.

    
respondido por el wolfgangsz 30.06.2011 - 14:25
7

Un poco de Google aparece Órdenes iniciales de EDSAC de finales de los años 40. Dado que fue el primer ensamblador, probablemente fue codificado en lenguaje de máquina.

Luego vinieron los ensambladores para otras máquinas, como SOAP I y II para El IBM 650. SOAP Probablemente también estaba codificado en lenguaje de máquina, aunque no he encontrado la declaración definitiva.

Un poco más tarde llegó Fortran (traductor de fórmulas), para el IBM 704. Presumiblemente fue escrito en ensamblador para el 704. Un ensamblador temprano para el 701 se acredita a Nathan Rochester .

Si desea obtener una idea de cómo programar una computadora en lenguaje de máquina, visite uno de mis sitios favoritos, La computadora de relevo de Harry Porter .

    
respondido por el Mike Dunlavey 30.06.2011 - 15:13
6

Es posible (si es tedioso) escribir código de máquina directo. Tal vez escriba el programa en un ensamblador en un pedazo de papel y luego lo traduzca a mano en las instrucciones numéricas del código de máquina que ingresa en la memoria de la máquina. Incluso puede omitir el paso de ensamblador en papel si ha memorizado los valores numéricos de todas las instrucciones del código de máquina. ¡No es raro en esos días, créalo o no!

Las primeras computadoras fueron programadas directamente en binario al conmutar los interruptores físicos. Fue una gran mejora en la productividad cuando el hardware evolucionó para permitir que el programador (o el asistente de ingreso de datos) ingrese el código en números hexadecimales a través de un teclado numérico.

Un ensamblador de software solo se volvió relevante cuando se disponía de más memoria (ya que el código del ensamblador ocupa más espacio que el código de máquina sin procesar) y el hardware evolucionó para permitir la entrada alfanumérica. Así que los primeros ensambladores fueron escritos directamente por personas que dominaban el código de la máquina.

Cuando tienes un ensamblador, puedes escribir un compilador para un lenguaje de nivel superior en ensamblador.

La historia de C tiene múltiples pasos. El primer compilador de C se escribió en B (un antecesor de C) que a su vez se escribió en BCPL. BCPL es un lenguaje bastante simple (por ejemplo, no tiene tipos en absoluto), pero aún es un paso adelante del ensamblador en bruto. Así que ya ves cómo los lenguajes gradualmente más complejos se construyen en lenguajes más simples hasta el ensamblador. Y en sí, C es un lenguaje bastante pequeño y simple para los estándares de hoy.

Hoy en día, el primer compilador para un nuevo lenguaje a menudo se escribe en C, pero cuando el lenguaje alcanza una cierta madurez, a menudo se reescribe "en sí mismo". El primer compilador de Java se escribió en C, pero luego se reescribió en Java. El primer compilador de C # se escribió en C ++, pero recientemente se ha reescrito en C #. El compilador / intérprete de Python está escrito en C, pero el proyecto PyPy es un intento de volver a escribirlo en Python.

Sin embargo, no siempre es posible escribir un compilador / intérprete para un idioma en el idioma mismo. Existe un intérprete de JavaScript escrito en JavaScript, pero los compiladores / intérpretes en los navegadores actuales todavía están escritos en C o C ++ por razones de rendimiento. JavaScript escrito en JavaScript es simplemente demasiado lento.

Pero no tienes que usar C como el "idioma de inicio" para un compilador. El primer compilador de F # se escribió en OCaml, que es el otro idioma que está más relacionado con F #. Cuando se completó el compilador, se reescribió en F #. El primer compilador para Perl 6 fue escrito en Haskell (un lenguaje funcional puro muy diferente de Perl) pero ahora tiene un compilador escrito en C.

Un caso interesante es Rust, donde el primer compilador se escribió en OCaml (ahora se reescribe en Rust). Esto es notable porque OCaml generalmente se considera un nivel más alto que Rust, que es un lenguaje de sistemas más cercano al metal. Por lo tanto, no siempre se implementan lenguajes de nivel superior en idiomas de nivel inferior, también puede ser al revés.

    
respondido por el JacquesB 05.06.2015 - 14:44
3

Suponiendo que está comenzando con un conjunto de instrucciones simple y nada más, comenzaría creando un ensamblador o compilador minimal , apenas funcional, que puede cargar un archivo, analizar un mínimo un subconjunto del idioma de destino y genere un archivo ejecutable como salida, escribiendo el código de máquina sin procesar con un editor hexadecimal o similar.

Luego, usaría ese compilador o ensamblador apenas funcional para implementar un compilador o ensamblador ligeramente más capaz que pueda reconocer un subconjunto más grande del idioma de destino. Haga espuma, enjuague, repita, hasta que tenga el producto final.

    
respondido por el John Bode 30.06.2011 - 15:51
2

No es tan difícil, como parece. En la infancia;) hice un poco de desmontaje x86 en mente.

Incluso no necesitas aprenderlo especialmente. Simplemente sucede, cuando puede programar en ASM y luego tratar de arreglar un binario de terceros usando desensambladores interactivos. O al escribir su propia protección con cifrado de código.

I.e. a veces está migrando incluso de un idioma a un código sin ninguna maravilla.

    
respondido por el Pavel Koryagin 30.06.2011 - 19:30
1

Los primeros compiladores se implementaron utilizando lenguaje ensamblador. Y los primeros ensambladores se implementaron codificando programas en binario ...

No hace tanto tiempo que la programación en binario seguía siendo una habilidad que utilizaban las personas.

Cuando era un estudiante universitario, recuerdo haber realizado un ejercicio de programación que implicaba escribir un pequeño programa en el código de máquina PDP-8 (creo), ingresarlo a través de los interruptores del panel frontal y ejecutarlo. Un par de años después, me compré un kit de desarrollo del sistema 6502 que tenía un teclado hexadecimal para ingresar programas ... y 4k bytes de RAM.

    
respondido por el Stephen C 09.06.2013 - 17:32
-3

UNA RESPUESTA MUY SIMPLE Supongamos que escribimos un programa cableado y lo almacenamos en la ROM. Se puede considerar como compilador. Lo único que quiero decir es que el primer compilador fue cableado. A medida que la tecnología mejoraba, estos compiladores simples se usaban para escribir compiladores de alto nivel.

    
respondido por el DINOTOPO 05.06.2015 - 14:25

Lea otras preguntas en las etiquetas