Come sono stati realizzati i primi compilatori?

69

Mi sono sempre chiesto questo, e forse ho bisogno di una buona lezione di storia sui linguaggi di programmazione. Ma dato che la maggior parte dei compilatori oggigiorno sono realizzati in C, come sono stati realizzati i primissimi compilatori (AKA prima di C) o se tutte le lingue sono state interpretate?

Detto ciò, non capisco ancora come sia stato fatto il primo linguaggio assembly, capisco cosa sia il linguaggio assembly, ma non vedo come abbiano funzionato il linguaggio MOLTO primo assembly (come, come hanno fatto effettuare i primi comandi (come mov R21 ) o w / e impostare l'equivalente binario?

    
posta gnat 30.06.2011 - 14:13
fonte

9 risposte

88

Ha, l'ho fatto. Molte CPU hanno istruzioni semplici e di dimensioni fisse lunghe solo un paio di byte. Ad esempio, per una CPU semplice come Motorola 6800, è possibile adattare tutte le sue istruzioni su un singolo foglio di carta . Ad ogni istruzione è associato un codice operativo a due byte e argomenti. Potresti assemblare a mano un programma controllando il codice operativo di ciascuna istruzione. Dovresti quindi scrivere il tuo programma su carta , annotando ogni istruzione con il relativo codice operativo. Una volta che hai scritto il tuo programma, potresti masterizzare ogni opcode in sequenza ad una EPROM che poi memorizzerebbe il tuo programma. Collega la EPROM alla CPU con le giuste istruzioni agli indirizzi giusti e hai un programma di lavoro semplice. E per rispondere alla tua prossima domanda, sì. E 'stato doloroso (lo abbiamo fatto al liceo). Ma devo dire che il cablaggio di ogni chip in un computer a 8 bit e la scrittura manuale di un programma mi hanno dato una profondità di comprensione dell'architettura del computer che probabilmente non avrei potuto ottenere in nessun altro modo.

I chip più avanzati (come x86) sono molto più difficili da codificare a mano, perché spesso hanno istruzioni di lunghezza variabile. Processori VLIW / EPIC come Itanium sono praticamente impossibili da gestire a mano in modo efficiente perché trattare in pacchetti di istruzioni che sono ottimizzati e assemblati da compilatori avanzati. Per le nuove architetture, i programmi vengono quasi sempre scritti e assemblati su un altro computer, quindi caricati nella nuova architettura. Infatti, per aziende come Intel che effettivamente costruiscono CPU, possono eseguire programmi reali su architetture che non esistono ancora eseguendole su simulatori. Ma sto divagando ...

Per quanto riguarda i compilatori, nella loro forma più semplice, possono essere poco più di programmi "taglia e incolla". Potresti scrivere un "linguaggio di alto livello" molto semplice, non ottimizzante, che raggruppa semplicemente semplici istruzioni di linguaggio di assemblaggio senza un grande sforzo.

Se desideri una cronologia di compilatori e linguaggi di programmazione, ti suggerisco di GOTO una cronologia di FORTRAN .

    
risposta data 30.06.2011 - 14:23
fonte
54

Questo è ciò che bootstrap del compilatore riguarda (dal momento che nessuno ha menzionato come si chiama =).

the process of writing a compiler (or assembler) in the target programming language which it is intended to compile. Applying this technique leads to a self-hosting compiler.

Many compilers for many programming languages are bootstrapped, including compilers for BASIC, ALGOL, C, Pascal, PL/I, Factor, Haskell, Modula-2, Oberon, OCaml, Common Lisp, Scheme, Java, Python, Scala and more...

The chicken and egg problem

If one needs a compiler for language X to obtain a compiler for language X (which is written in language X), how did the first compiler get written? Possible methods to solving this chicken or the egg problem include:

  • Implementing an interpreter or compiler for language X in language Y. Niklaus Wirth reported that he wrote the first Pascal compiler in Fortran.
  • Another interpreter or compiler for X has already been written in another language Y; this is how Scheme is often bootstrapped.
  • Earlier versions of the compiler were written in a subset of X for which there existed some other compiler; this is how some supersets of Java, Haskell, and the initial Free Pascal compiler are bootstrapped.
  • The compiler for X is cross compiled from another architecture where there exists a compiler for X; this is how compilers for C are usually ported to other platforms. Also this is the method used for Free Pascal after the initial bootstrap.
  • Writing the compiler in X; then hand-compiling it from source (most likely in a non-optimized way) and running that on the code to get an optimized compiler. Donald Knuth used this for his WEB literate programming system...
    
risposta data 30.06.2011 - 15:59
fonte
15

In definitiva tutti i computer operano su codici binari, che vengono inseriti nella CPU. Questi codici binari sono perfettamente naturali per una CPU, ma anche perfettamente inutili per gli esseri umani. Uno dei primi modi per scrivere un programma è stato perforando i buchi nelle carte. La posizione dei fori rappresentava una particolare posizione di bit all'interno di una parola e la presenza o l'assenza del foro veniva interpretata come zero o uno. Queste carte sono state messe nella giusta sequenza in una scatola, e poi introdotte in un lettore di schede, che le ha effettivamente convertite in codice binario per la CPU (e la tua vita è stata effettivamente persa se hai lasciato cadere la scatola).

Ovviamente i primi programmatori hanno elaborato i codici binari uno per uno e avevano una macchina per perforare le carte. Questa è essenzialmente una programmazione in linguaggio assembly su mani e ginocchia. Una volta ottenuto ciò, è possibile creare tutte le altre cose da esso: un semplice editor di testo, un compilatore di linguaggio assembly (per convertire le istruzioni di assembly di testo in codici binari), un linker e un loader. E il resto, come si suol dire, è storia.

    
risposta data 30.06.2011 - 14:25
fonte
7

Un po 'googling su Ordini iniziali EDSAC dalla fine degli anni '40. Poiché era il primo assemblatore, probabilmente era codificato in linguaggio macchina.

Più tardi sono arrivati gli assemblatori per altre macchine, come SOAP I e II per l'IBM 650. SOAP I era probabilmente anche codificato in linguaggio macchina, anche se non ho trovato la dichiarazione definitiva.

Poco dopo arrivò Fortran (traduttore di formula), per IBM 704. Presumibilmente è stato scritto in assembler per il 704. Un precoce assemblatore per il 701 è accreditato su Nathan Rochester .

Se vuoi avere un'idea di come programmare un computer in linguaggio macchina, controlla uno dei miei siti preferiti, Computer di inoltro di Harry Porter .

    
risposta data 30.06.2011 - 15:13
fonte
6

È possibile (se noioso) scrivere codice macchina diretto. Magari scrivi il programma in assembler su un pezzo di carta e poi lo traduci a mano nelle istruzioni numeriche del codice macchina che inserisci nella memoria della macchina. Puoi persino saltare il passaggio assemblatore su carta se hai memorizzato i valori numerici di tutte le istruzioni del codice macchina - non insolito in quei giorni, che ci crediate o no!

I primi computer sono stati programmati direttamente in binario attivando i commutatori fisici. È stato un notevole miglioramento della produttività quando l'hardware si è evoluto per consentire al programmatore (o all'addetto all'immissione dati) di immettere il codice in numeri esadecimali tramite una tastiera!

Un assemblatore di software è diventato rilevante solo quando è disponibile più memoria (dal momento che il codice assembler occupa più spazio del codice macchina grezzo) e l'hardware si è evoluto per consentire l'input alfanumerico. Quindi i primi assemblatori sono stati scritti direttamente da persone che parlano correntemente il codice della macchina.

Quando hai un assemblatore, puoi scrivere un compilatore per un linguaggio di livello superiore nell'assemblatore.

La trama di C ha più passaggi. Il primo compilatore C è stato scritto in B (un predecessore di C) che a sua volta è stato scritto in BCPL. BCPL è un linguaggio piuttosto semplice (per esempio non ha affatto tipi), ma è comunque un passo avanti rispetto all'assemblatore non elaborato. Così vedi come gradualmente le lingue più complesse si costruiscono in linguaggi più semplici fino al montaggio. E di per sé C è un linguaggio piuttosto piccolo e semplice secondo gli standard di oggi.

Oggi, il primo compilatore per una nuova lingua è spesso scritto in C, ma quando la lingua raggiunge una certa maturità viene spesso riscritta "in sé". Il primo compilatore Java è stato scritto in C, ma successivamente è stato riscritto in Java. Il primo compilatore C # è stato scritto in C ++, ma recentemente è stato riscritto in C #. Il compilatore / interprete Python è scritto in C, ma il progetto PyPy è un tentativo di riscriverlo in Python.

Tuttavia non è sempre possibile scrivere un compilatore / interprete per una lingua nella stessa lingua. Esiste un interprete JavaScript scritto in JavaScript, ma i compilatori / interpreti nei browser correnti sono ancora scritti in C o C ++ per motivi di prestazioni. JavaScript scritto in JavaScript è semplicemente troppo lento.

Ma non devi usare C come "lingua di partenza" per un compilatore. Il primo compilatore F # è stato scritto in OCaml, che è l'altra lingua più strettamente correlata a F #. Quando il compilatore è stato completato, è stato riscritto in F #. Il primo compilatore per Perl 6 è stato scritto in Haskell (un linguaggio puramente funzionale molto diverso da Perl) ma ora ha un compilatore scritto in C.

Un caso interessante è Rust, in cui il primo compilatore è stato scritto in OCaml (ora è riscritto in Rust). Ciò è notevole perché OCaml è generalmente considerato di livello superiore rispetto a Rust, che è un linguaggio di sistema più vicino al metallo. Quindi non sono sempre le lingue di livello superiore implementate nei linguaggi di livello inferiore, potrebbe anche essere il contrario.

    
risposta data 05.06.2015 - 14:44
fonte
3

Supponendo che inizi con un set di istruzioni nulle e nient'altro, inizi a creare un assemblatore o compilatore minimal , appena funzionante, che può caricare un file, analizzare un minimo sottoinsieme della lingua di destinazione e generare un file eseguibile come output, scrivendo il codice macchina grezzo utilizzando un editor esadecimale o simile.

Utilizzeresti quindi un compilatore o un assemblatore appena funzionante per implementare un compilatore o un assemblatore leggermente più capace in grado di riconoscere un sottoinsieme più ampio della lingua di destinazione. Mescolare, sciacquare, ripetere, fino a quando non si ottiene il prodotto finale.

    
risposta data 30.06.2011 - 15:51
fonte
2

Non è così difficile, come sembra. Nell'infanzia;) Ho fatto alcuni x86 di disassemblaggio in mente.

Non hai nemmeno bisogno di impararlo in particolare. Succede semplicemente, quando sei in grado di programmare in ASM e poi provare a correggere un binario di terze parti usando disassemblatori interattivi. O quando scrivi la tua protezione con la crittografia del codice.

vale a dire. a volte stai migrando anche dalla lingua ai codici senza meraviglia.

    
risposta data 30.06.2011 - 19:30
fonte
1

I primi compilatori sono stati implementati usando il linguaggio assembly. E i primi assemblatori sono stati implementati tramite programmi di codifica in binario ...

Non è molto tempo fa che la programmazione in binario era ancora un'abilità che le persone utilizzavano.

Quando ero uno studente universitario, ricordo di aver fatto un esercizio di programmazione che comportava la scrittura di un minuscolo programma nel codice macchina PDP-8 (credo), inserendolo tramite gli interruttori del pannello frontale e eseguendolo. Un paio d'anni dopo, mi sono comprato un kit di sviluppo del sistema 6502 con tastiera esadecimale per l'inserimento dei programmi ... e 4k byte di RAM.

    
risposta data 09.06.2013 - 17:32
fonte
-3

UNA RISPOSTA MOLTO SEMPLICE Supponiamo di scrivere un programma cablato e di memorizzarlo in ROM. Può essere considerato come compilatore. Quindi voglio semplicemente dire che il primo compilatore è stato cablato. Con il miglioramento della tecnologia, questi semplici compilatori sono stati utilizzati per scrivere compilatori di alto livello.

    
risposta data 05.06.2015 - 14:25
fonte

Leggi altre domande sui tag