I primi assemblatori sono stati scritti in codice macchina?

41

Sto leggendo il libro Gli elementi dei sistemi informatici: costruire un computer moderno dai primi principi , che contiene progetti comprendendo la costruzione di un computer dai cancelli booleani fino alle applicazioni di alto livello (in quest'ordine). L'attuale progetto su cui sto lavorando è scrivere un assemblatore usando un linguaggio di alto livello a mia scelta, per tradurre dal codice assembly Hack al codice macchina Hack (Hack è il nome della piattaforma hardware costruita nei capitoli precedenti). Sebbene l'hardware sia stato interamente costruito in un simulatore, ho provato a fingere di costruire davvero ogni livello usando solo gli strumenti a mia disposizione in quel momento del processo reale.

Detto questo, mi ha fatto pensare. Usare un linguaggio di alto livello per scrivere il mio assemblatore è certamente conveniente, ma per il primissimo assemblatore mai scritto (cioè nella storia), non dovrebbe essere scritto in codice macchina, dato che è tutto ciò che esisteva in quel momento?

E una domanda correlata ... che ne dici di oggi? Se viene fuori una nuova architettura della CPU, con un set di istruzioni completamente nuovo e una sintassi di assemblaggio completamente nuova, come sarà costruito l'assemblatore? Suppongo che si possa ancora usare un linguaggio di alto livello esistente per generare binari per il programma assemblatore, dal momento che se si conosce la sintassi di entrambi i linguaggi di assemblaggio e macchina per la nuova piattaforma, allora il compito di scrivere l'assemblatore è davvero solo un compito di analisi del testo e non è inerentemente correlato a quella piattaforma (cioè deve essere scritto nel linguaggio macchina di quella piattaforma) ... che è la vera ragione per cui sono in grado di "imbrogliare" mentre scrivo il mio assemblatore Hack nel 2012, e usare alcuni preesistenti un linguaggio di alto livello per aiutarmi.

    
posta The111 08.01.2012 - 21:23
fonte

10 risposte

36

for the very first assembler ever written (i.e. in history), wouldn't it need to be written in machine code

Non necessariamente. Naturalmente la prima versione v0.00 dell'assemblatore deve essere stata scritta in codice macchina, ma non sarebbe stata sufficientemente potente per essere chiamata assemblatore. Non supporterebbe nemmeno la metà delle funzionalità di un assemblatore "reale", ma sarebbe sufficiente scrivere la prossima versione di se stesso. Quindi puoi riscrivere v0.00 nel sottoinsieme del linguaggio assembly, chiamarlo v0.01, usarlo per creare il prossimo set di funzionalità del tuo assembler v0.02, quindi utilizzare v0.02 per creare v0.03, e così via, fino ad arrivare alla v1.00. Come risultato, solo la prima versione sarà in codice macchina; la prima versione rilasciata sarà nella lingua dell'assembly.

Ho lo sviluppo bootstrap di un compilatore di linguaggio template usando questo trucco. La mia versione iniziale utilizzava le dichiarazioni di printf , ma la prima versione che ho utilizzato nella mia azienda utilizzava il processore di template che stava elaborando. La fase di bootstrap è durata meno di quattro ore: non appena il mio processore ha potuto produrre un output a malapena utile, l'ho riscritto nella sua lingua, compilato, e ho gettato via la versione non basata su modelli.

    
risposta data 08.01.2012 - 21:42
fonte
23

Secondo Wikipedia, il primo linguaggio assemblatore / assemblaggio è stato implementato per IBM 701 da Nathaniel Rochester . (Le date sono un po 'incerte dall'articolo di Wikipedia: afferma che Rochester è entrato a far parte di IBM nel 1948, ma un'altra pagina di Wikipedia afferma che il 701 è stato annunciato pubblicamente nel 1952. E questa pagina IBM afferma che " [a] progetto effettivo iniziato il 1 febbraio 1951 e completato un anno dopo ".)

Tuttavia "Assemblatori e caricatori" di David Salomon afferma (a pagina 7) che EDSAC aveva anche un assemblatore:

"One of the first stored program computers was the EDSAC (Electronic Delay Storage Automatic Calculator) developed at Cambridge University in 1949 by Maurice Wilkes and W. Renwick. From its very first days the EDSAC had an assembler, called Initial Orders. It was implemented in a read-only memory formed from a set of rotary telephone selectors, and it accepted symbolic instructions. Each instruction consisted of a one letter mnemonic, a decimal address, and a third field that was a letter. The third field caused one of 12 constants preset by the programmer to be added to the address at assembly time." (References omitted ... see the original.)

Supponendo che accettiamo che gli "Ordini Iniziali" abbiano la precedenza, abbiamo la prova evidente che il primo assemblatore è stato implementato nel codice macchina.

Questo modello (scrivendo gli assemblatori iniziali in codice macchina) sarebbe stato la norma negli anni '50. Tuttavia, secondo Wikipedia , "[a] gli ssembler sono stati i primi strumenti linguistici per il bootstrap" . Vedi anche questa sezione che spiega come è stato usato un codice macchina assembler primordiale scritto per avviare un assemblatore più avanzato che è stato codificato in linguaggio assembly.

Oggigiorno assemblatori e compilatori sono scritti in linguaggi di livello superiore e un assemblatore o compilatore per una nuova architettura di macchina viene tipicamente sviluppato su un'architettura diversa e compilato in modo incrociato.

(FWIW - la scrittura e il debug di programmi non banali in codice macchina è un processo estremamente laborioso: qualcuno che sviluppa un assemblatore in codice macchina molto probabilmente lo avvia a un assemblatore scritto in assembler il prima possibile.)

Questa pagina di Wikipedia su compilatori e assemblatori di bootstrapping vale la pena leggere ... se questo è tutto sconcertante per te.

    
risposta data 09.01.2012 - 06:09
fonte
14

Presumo che i primi assemblatori siano stati scritti in codice macchina, perché come dici tu, al momento non c'era altro disponibile.

Oggi, tuttavia, quando esce una nuova architettura della CPU, usiamo il cosiddetto un Cross-Compiler , che è un compilatore che produce codice macchina non per l'architettura su cui è in esecuzione, ma per un'architettura diversa.

(In effetti, come sono sicuro che scoprirai più avanti nel libro che stai leggendo, non c'è assolutamente nulla che renda un compilatore intrinsecamente più adatto a produrre codice macchina per l'architettura su cui è in esecuzione che su qualsiasi altra architettura: è solo questione di quale architettura tu, come il creatore del compilatore, sceglierai come target.)

Quindi oggi è persino possibile (almeno in teoria) creare un'architettura nuova di zecca e avere su di sé programmi di compilazione di linguaggi di alto livello (compilati su altre architetture usando cross-compilatori) prima ancora di avere un assemblatore per quella architettura.

    
risposta data 08.01.2012 - 21:45
fonte
12

Al primo "assemblaggio" è stato scritto su carta e poi manualmente "compilato" su schede perforate.

Mio nonno lavorava con un ZRA1 (scusa, la pagina esiste solo in tedesco, ma la traduzione di Google è ok al punto da poter effettivamente raccogliere i fatti più importanti: D).
Il modus operandi era di scrivere il tuo codice su carta in una sorta di linguaggio di assemblaggio e la segretaria avrebbe effettivamente eseguito la trascrizione per perforare le schede, quindi passarle all'operatore e il risultato sarebbe stato restituito la mattina successiva.

Tutto ciò era essenzialmente prima che i programmatori avessero il lusso di inserire i dati attraverso una tastiera e visualizzarli su uno schermo.

    
risposta data 09.01.2012 - 11:48
fonte
9

È difficile essere certi del primo assemblatore molto (difficile persino definire cosa fosse). Anni fa, quando scrissi alcuni assemblatori per macchine prive di assemblatori, scrivevo ancora il codice in linguaggio assembly. Poi, dopo aver ragionevolmente completato una sezione di codice, l'ho tradotto manualmente in codice macchina. Quelle erano ancora due fasi completamente separate però - quando stavo scrivendo il codice, non stavo lavorando o pensando a un livello di codice macchina affatto.

Devo aggiungere che in alcuni casi ho fatto un passo in più: ho scritto la maggior parte del codice in un linguaggio assembly che ho trovato più semplice da usare, quindi ho scritto un piccolo kernel (più o meno quello che ora chiameremmo macchina virtuale) per interpretarlo sul processore di destinazione. Questo è stato mortalmente lento (specialmente su un processore da 1 MHz a 8 bit), ma non importava molto, dal momento che normalmente veniva eseguito solo una volta (o al massimo alcune volte).

    
risposta data 09.01.2012 - 03:59
fonte
8

Non è necessario un assemblatore per assemblare il codice lingua dell'assemblaggio nel codice macchina. Proprio come non hai bisogno di un editor per scrivere codice linguaggio assembly.

Una prospettiva storica

I primi assemblatori furono probabilmente scritti in linguaggio assembly e poi assemblati a mano in codice macchina. Anche se il processore non avesse un "linguaggio assembly" ufficiale, i programmatori probabilmente hanno fatto la maggior parte del lavoro di programmazione usando una sorta di pseudo-codice prima di tradurre quel codice in istruzioni macchina.

Anche nei primi giorni dell'informatica , i programmatori hanno scritto programmi in una sorta di notazione simbolica e li abbiamo tradotti in codice macchina prima di inserirli nel loro computer. Nel caso di Augusta Ada King, avrebbe dovuto tradurli in schede perforate per Babbage 's Motore analitico , ma purtroppo non è mai stato costruita.

Esperienza personale

Il primo computer che possedevo era un Sinclair ZX81 (Timex 1000 negli Stati Uniti). Il retro del manuale contiene tutte le informazioni necessarie per tradurre il linguaggio assembly Z80 in codice macchina (includendo anche tutti gli strani modi opcode lo Z80 aveva).

Scriverò un programma (su supporto cartaceo) in linguaggio assembly e eseguirò la scansione a secco del codice. Quando ero felice che il mio programma fosse privo di bug, avrei cercato ogni istruzione nel retro del manuale, tradurlo in codice macchina e scrivere anche il codice macchina sulla carta. Infine, inserisco tutte le istruzioni del codice macchina nel mio ZX81 prima di salvarlo su nastro e provare ad eseguirlo.

Se non funzionasse, vorrei ricontrollare il mio assemblaggio a mano e se una traduzione fosse sbagliata correggerei i byte caricati dal nastro prima di ri-salvarlo e provare di nuovo ad eseguire il programma.

Dall'esperienza, posso dirti che è molto più facile eseguire il debug del tuo codice se è scritto in linguaggio assembly rispetto al codice macchina - da qui la popolarità dei disassemblatori. Anche se non hai un assemblatore, assemblare a mano è meno soggetto a errori che provare a scrivere codice macchina direttamente, anche se suppongo che un vero programmatore come Mel potrebbe non essere d'accordo. * 8' )

    
risposta data 09.01.2012 - 14:37
fonte
5

Non c'è differenza allora o ora. Vuoi inventare un nuovo linguaggio di programmazione, scegli una delle lingue disponibili oggi per creare il primo compilatore. per un certo periodo di tempo, se si tratta di un obiettivo del progetto, si crea un compilatore in quella lingua e si può quindi auto-ospitare.

Se tutto ciò che avevi era carta e penna e alcuni interruttori o schede perforate come interfaccia utente per il primo o il prossimo set di istruzioni, hai utilizzato uno o tutti gli elementi disponibili. Potresti benissimo aver scritto un linguaggio assembly, su carta, e poi hai usato un assemblatore, tu, per convertirlo in codice macchina, magari in ottale, poi a un certo punto nell'interfaccia della macchina.

Quando un set di istruzioni nuovo di zecca è inventato oggi, non è diverso, a seconda della compagnia / individui, delle pratiche, ecc. è abbastanza probabile che l'ingegnere hardware probabilmente programmando in verilog o vhdl, scriva i primi pochi programmi di test a mano in codice macchina (probabilmente in hex o binario). a seconda del progresso del team del software, potrebbero passare molto rapidamente o per un lungo periodo a passare al linguaggio assembly e quindi a un compilatore.

Le prime macchine informatiche non erano macchine generiche da utilizzare per creare assemblatori e compilatori. Li hai programmati spostando alcuni fili tra l'uscita dell'alimentatore precedente e l'ingresso del successivo. Alla fine si disponeva di un processore generico in modo tale da poter scrivere un assemblatore in assemblaggio, assemblarlo a mano, inserirlo come codice macchina, quindi utilizzarlo per analizzare ebcdic, ascii, ecc. E quindi self-host. memorizza il file binario su un supporto che potresti leggere / caricare in un secondo momento senza dover mantenere gli interruttori di flipping nel codice della macchina per l'alimentazione manuale.

Pensa a schede perforate e nastro di carta. Invece di commutare gli interruttori si potrebbe sicuramente fare una macchina completamente meccanica, un dispositivo per risparmiare lavoro, che ha creato il supporto che il computer avrebbe letto. Invece di dover inserire i bit del codice macchina con interruttori come un'altair, si potrebbe invece alimentare il nastro di carta o le schede perforate (usando qualcosa di meccanico, non guidato dal processore, che alimentava la memoria o il processore, OPPURE usando un caricatore di avvio scritto con un codice macchina piccolo). Questa non era una cattiva idea perché potresti creare qualcosa, guidato dal computer che potrebbe anche produrre meccanicamente i nastri di carta o le schede perforate, e quindi reinserirli. Due fonti di schede perforate, il dispositivo per risparmiare lavoro meccanico non basato sul computer e la macchina computerizzata. entrambi producono i "binari" per il computer.

    
risposta data 13.01.2012 - 05:27
fonte
4

Ci sono una o due istanze nello zoo del computer di Brook dove ha detto qualcosa come "i mnemonici sono la nostra invenzione, il progettista ha semplicemente usato l'opcode numerico o il carattere il cui codice era l'opcode", quindi dove macchine per cui non c'era nemmeno un linguaggio assembly.

Entrando nei programmi, esegui il debug sul pannello frontale (per coloro che non l'hanno fatto, era un modo per impostare la memoria, hai impostato alcuni switch per l'indirizzo, altri per il valore e premuto un pulsante, o un altro pulsante per leggere il valore) era comune molto più tardi. Alcuni vecchi timer si vantano di poter ancora inserire il codice di avvio per i computer che hanno utilizzato ampiamente.

La difficoltà di scrivere direttamente il codice macchina e di leggere i programmi dal dump della memoria dipende in gran parte dal linguaggio macchina, alcuni sono relativamente facili (la parte più difficile è il tracciamento degli indirizzi), x86 è uno dei peggiori.

    
risposta data 09.01.2012 - 10:08
fonte
2

Ho costruito un computer nel 1975. Era molto avanzato sulla sua contemporanea Altair, perché aveva un "monitor rom" che mi permetteva di inserire programmi digitando il codice macchina in esadecimale e visualizzando questo codice su un monitor video, dove come con l'Altair ogni istruzione della macchina doveva essere inserita un po 'alla volta usando una fila di interruttori.

Quindi sì, agli albori dei computer e poi ancora nei primi giorni dei personal computer le persone scrivevano applicazioni in codice macchina.

    
risposta data 09.01.2012 - 16:29
fonte
2

Un aneddoto:

Quando ho imparato il linguaggio assembly, su Apple] [ c'era un programma incluso nella ROM chiamato micro-assemblatore. Ha fatto la traduzione immediata delle istruzioni di assemblaggio in byte, mentre le immettevi. Ciò significa che non c'erano etichette: se si desidera saltare o caricare, è necessario calcolare le compensazioni da soli. Era molto più facile che cercare i layout delle istruzioni e inserire valori esadecimali.

Senza dubbio, i veri assemblatori sono stati scritti per la prima volta usando il micro-assemblatore o qualche altro ambiente non del tutto completo.

    
risposta data 13.01.2012 - 16:55
fonte

Leggi altre domande sui tag