Os primeiros assemblers foram escritos em código de máquina?

41

Estou lendo o livro Os elementos dos sistemas de computação: construindo um computador moderno a partir dos primeiros princípios , que contém projetos englobando a construção de um computador a partir de portas booleanas até aplicações de alto nível (nessa ordem). O projeto atual em que estou trabalhando é escrever um montador usando uma linguagem de alto nível de minha escolha, para traduzir do código de assembly Hack para o código de máquina Hack (Hack é o nome da plataforma de hardware construída nos capítulos anteriores). Embora o hardware tenha sido construído em um simulador, tentei fingir que estou realmente construindo cada nível usando apenas as ferramentas disponíveis para mim naquele momento no processo real.

Dito isso, isso me fez pensar. Usar uma linguagem de alto nível para escrever meu montador é certamente conveniente, mas para o primeiro montador já escrito (ou seja, na história), não precisaria ser escrito em código de máquina, já que era tudo o que existia na época?

E uma pergunta correlacionada ... e hoje? Se uma nova arquitetura de CPU for lançada, com um novo conjunto de instruções e uma nova sintaxe de montagem, como o montador será construído? Eu estou supondo que você ainda poderia usar uma linguagem de alto nível existente para gerar binários para o programa assembler, já que se você conhece a sintaxe das linguagens de montagem e de máquina para sua nova plataforma, então a tarefa de escrever o montador é realmente apenas um tarefa de análise de texto e não está inerentemente relacionada a essa plataforma (ou seja, precisando ser escrita na linguagem de máquina dessa plataforma) ... que é a razão pela qual eu posso "trapacear" ao escrever meu montador de Hack em 2012, e usar alguns preexistentes linguagem de alto nível para me ajudar.

    
por The111 08.01.2012 / 21:23
fonte

10 respostas

35

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

Não necessariamente. É claro que a primeira versão v0.00 do assembler deve ter sido escrita em código de máquina, mas não seria suficientemente poderosa para ser chamada de assembler. Não suportaria nem a metade dos recursos de um montador "real", mas seria suficiente escrever a próxima versão de si mesmo. Então você poderia reescrever v0.00 no subconjunto da linguagem de montagem, chamá-lo v0.01, usá-lo para construir o próximo conjunto de recursos do seu assembler v0.02, então usar v0.02 para construir a v0.03, e assim por diante, até chegar à v1.00. Como resultado, somente a primeira versão estará em código de máquina; a primeira versão lançada estará na linguagem assembly.

Eu criei bootstrap no desenvolvimento de um compilador de linguagem de template usando este truque. Minha versão inicial estava usando printf declarações, mas a primeira versão que eu coloquei para usar na minha empresa estava usando o processador muito modelo que estava processando. A fase de bootstraping durou menos de quatro horas: assim que meu processador pudesse produzir uma saída pouco útil, eu o reescrevi em sua própria linguagem, compilado e joguei fora a versão não modelada.

    
por 08.01.2012 / 21:42
fonte
23

De acordo com a Wikipedia, a primeira linguagem assembler / assembly foi implementada para o IBM 701 por Nathaniel Rochester . (As datas são um pouco incertas do artigo da Wikipedia. Ele afirma que Rochester entrou para a IBM em 1948, mas outra página da Wikipedia afirma que o 701 foi anunciado publicamente em 1952. E esta página da IBM declara que " [o] design foi iniciado em 1 de fevereiro de 1951 e foi concluído um ano depois ".)

No entanto, "Assembler and Loaders", por David Salomon , afirma (na página 7) que a EDSAC também um montador:

"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.)

Assumindo que aceitamos que "Pedidos iniciais" tem precedência, temos evidências claras de que o primeiro assembler foi implementado em código de máquina.

Esse padrão (escrever os montadores iniciais em código de máquina) teria sido a norma até os anos 1950. No entanto, de acordo com a Wikipedia , "os ssemblers foram as primeiras ferramentas linguísticas a se autoinstruir" . Veja também esta seção que explica como um código de máquina escrito primordial assembler foi usado para inicializar um montador mais avançado que foi codificado em linguagem assembly.

Atualmente, montadores e compiladores são escritos em linguagens de alto nível, e um montador ou compilador para uma nova arquitetura de máquina é tipicamente desenvolvido em uma arquitetura diferente e cross-compilado.

(FWIW - escrever e depurar programas não-triviais em código de máquina é um processo excessivamente trabalhoso. Alguém desenvolvendo um montador em código de máquina provavelmente inicializaria para um montador escrito em assembler o mais rápido possível.)

Esta página da Wikipedia sobre compiladores e montadores de bootstrap vale a pena ser lida ... se isso for tudo desconcertante para você.

    
por 09.01.2012 / 06:09
fonte
14

Eu presumo que os primeiros montadores foram escritos em código de máquina, porque, como você diz, nada mais estava disponível naquela época.

Hoje, no entanto, quando uma nova arquitetura de CPU é lançada, usamos o que é conhecido como um Cross-Compiler , que é um compilador que produz código de máquina não para a arquitetura em que está sendo executado, mas para uma arquitetura diferente.

(Na verdade, como tenho certeza que você descobrirá mais adiante no livro que está lendo, não há absolutamente nada que torne um compilador inerentemente mais adequado para produzir código de máquina para a arquitetura na qual ele está sendo executado) do que em qualquer outra arquitetura. É apenas uma questão de qual arquitetura você, como o criador do compilador, vai direcionar.)

Então, hoje é possível (pelo menos em teoria) criar uma nova arquitetura e ter compiladores de linguagem de alto nível nativamente executados nela (compilados em outras arquiteturas usando cross-compilers) antes mesmo de você ter um assembler para essa arquitetura.

    
por 08.01.2012 / 21:45
fonte
12

No início, "montagem" foi escrita em papel e depois "compilada" manualmente em cartões perfurados.

Meu avô estava trabalhando com um ZRA1 (desculpe, a página só existe em alemão, mas a tradução do Google é ok até o ponto onde você pode realmente pegar os fatos mais importantes: D). O modus operandi era escrever o seu código no papel em uma espécie de linguagem de montagem e a secretária faria a transcrição para cartões perfurados, depois passaria para o operador e o resultado seria devolvido na manhã seguinte.

Tudo isso foi essencialmente antes que os programadores tivessem o luxo de inserir dados através de um teclado e visualizá-los em uma tela.

    
por 09.01.2012 / 11:48
fonte
9

É difícil ter certeza sobre o very primeiro montador (difícil de definir o que era). Anos atrás, quando escrevi alguns montadores para máquinas que não tinham montadores, ainda escrevia o código em linguagem assembly. Então, depois de ter uma seção de código razoavelmente completa, traduzi-a em código de máquina à mão. Essas ainda eram duas fases completamente separadas - quando eu estava escrevendo o código, eu não estava trabalhando ou pensando em um nível de código de máquina.

Devo acrescentar que, em alguns casos, dei mais um passo: escrevi a maior parte do código em uma linguagem de montagem que achei mais simples de usar, então escrevi um minúsculo kernel (mais ou menos o que agora chamamos de máquina virtual) para interpretar isso no processador de destino. Isso foi muito lento (especialmente em um processador de 1 MHz e 8 bits), mas isso não importava muito, já que normalmente só era executado uma vez (ou no máximo algumas vezes).

    
por 09.01.2012 / 03:59
fonte
8

Você não precisa de um montador para montar o código da linguagem de montagem no código da máquina. Assim como você não precisa de um editor para escrever o código da linguagem de montagem.

Uma perspectiva histórica

Os primeiros montadores foram provavelmente escritos em linguagem assembly e depois montados em código de máquina. Mesmo se o processador não tivesse uma 'linguagem de montagem' oficial, então os programadores provavelmente faziam a maior parte do trabalho de programação usando algum tipo de pseudocódigo antes de traduzir o código em instruções de máquina.

Mesmo nos primeiros dias da computação , os programadores escreveram programas em uma espécie de notação simbólica e as traduziu em código de máquina antes de ser inserido em seu computador. No caso de Augusta Ada King, ela precisaria traduzi-los para cartões perfurados para Mecanismo analítico da en.wikipedia.org/wiki/Charles_Babbage">Babbage , mas nunca foi construído.

Experiência pessoal

O primeiro computador que eu possuía era um Sinclair ZX81 (Timex 1000 nos EUA). A parte de trás do manual tinha todas as informações que você precisava para traduzir a linguagem de montagem Z80 em código de máquina (mesmo incluindo todos os modos estranhos de índice opcodes o Z80 tinha).

Eu escreveria um programa (em papel) na linguagem assembly e executaria o código a seco. Quando eu estava feliz que meu programa estava livre de bugs, eu procurava cada instrução na parte de trás do manual, traduzia-a em código de máquina e escrevia o código da máquina no papel também. Por fim, eu digitaria todas as instruções de código de máquina no meu ZX81 antes de salvá-las em fita e tentar executá-las.

Se não funcionasse, eu verificaria a montagem da minha mão e, se qualquer tradução estivesse errada, eu iria corrigir os bytes carregados da fita antes de salvá-la novamente e tentar executar novamente o programa.

Por experiência, posso dizer-lhe que é muito mais fácil depurar seu código se estiver escrito em assembly do que em código de máquina - daí a popularidade de desmontadores. Mesmo que você não tenha um montador, a montagem manual é menos propensa a erros do que tentar escrever código de máquina diretamente, embora eu ache que um programador real como o Mel pode discordar. * 8 ')

    
por 09.01.2012 / 14:37
fonte
5

Não há diferença então ou agora. Você quer inventar uma nova linguagem de programação, você escolhe uma das linguagens disponíveis hoje para fazer o primeiro compilador. em algum período de tempo, se for um objetivo do projeto, você cria um compilador nesse idioma e pode, então, se auto-hospedar.

Se tudo o que você tinha era lápis e papel e alguns comutadores ou cartões perfurados como interface do usuário para o primeiro ou o próximo conjunto de instruções, você usou um ou todos os itens disponíveis para você. Você poderia muito bem ter escrito uma linguagem de montagem, em papel, e depois usado um montador, você, para convertê-lo em código de máquina, talvez em octal, então em algum ponto que entrou na interface para a máquina.

Quando um novo conjunto de instruções é inventado hoje, não é diferente, dependendo da empresa / indivíduos, práticas, etc. É bastante provável que o engenheiro de hardware provavelmente programando em verilog ou vhdl, escreva os primeiros programas de teste manualmente em código de máquina (provavelmente em hexadecimal ou binário). Dependendo do progresso das equipes de software, elas podem muito rapidamente ou não, por um longo tempo, mudar para a linguagem assembly e, em seguida, para um compilador.

As primeiras máquinas de computação não eram máquinas de uso geral que você poderia usar para criar montadores e compiladores. Você os programou movendo alguns fios entre a saída do alu anterior e a entrada do próximo. Eventualmente, você tinha um processador de propósito geral para poder escrever um montador em uma montagem, montá-lo manualmente, alimentá-lo como código de máquina e usá-lo para analisar ebcdic, ascii, etc. e, em seguida, auto-host. armazene o binário em alguma mídia que você possa mais tarde ler / carregar sem precisar alternar os interruptores para o código da máquina de alimentação manual.

Pense em cartões perfurados e fita de papel. Em vez de trocar os interruptores, você poderia definitivamente fazer uma máquina completamente mecânica, um dispositivo de economia de trabalho, que criou a mídia que o computador iria ler. Em vez de ter que inserir os bits de código da máquina com switches como um altair, você poderia alimentar fita de papel ou cartões perfurados (usando algo mecânico, não acionado pelo processador, que alimentasse a memória ou processador, ou usando um carregador de inicialização de código de máquina pequeno). Esta não foi uma má idéia, porque você poderia fazer algo, impulsionado pelo computador que também poderia mecanicamente produzir as fitas de papel ou cartões perfurados, e depois alimentar as pessoas de volta. Duas fontes de cartões perfurados, o dispositivo de economia de mão-de-obra mecânica não baseado em computador. e a máquina acionada por computador. ambos produzem os "binários" para o computador.

    
por 13.01.2012 / 05:27
fonte
4

Há uma ou duas instâncias no zoológico de computadores de Brook onde ele disse algo como "os mnemônicos são nossa invenção, o designer simplesmente usou opcode numérico ou o caractere cujo código era o opcode", então onde máquinas para as quais não havia sequer uma linguagem de montagem.

A inserção de programas termina a depuração no painel frontal (para aqueles que não o fizeram, foi uma maneira de configurar a memória, você configurou alguns switches para o endereço, outros para o valor e pressionou um botão ou outro botão para ler o valor) era comum muito mais tarde. Alguns veteranos se gabam de que ainda seriam capazes de inserir o código de inicialização para máquinas que usaram extensivamente.

A dificuldade de escrever código de máquina diretamente e ler programas do despejo de memória é bastante dependente da linguagem de máquina, alguns deles são relativamente fáceis (a parte mais difícil é rastrear os endereços), x86 é um dos piores.

    
por 09.01.2012 / 10:08
fonte
2

Eu construí um computador em 1975. Era muito avançado sobre o seu contemporâneo Altair, porque ele tinha um 'monitor rom' que me permitia entrar em programas digitando código de máquina em hexadecimal e vendo este código em um monitor de vídeo, onde como com o Altair, cada instrução de máquina tinha que ser inserida um pouco no tempo usando uma linha de interruptores.

Então, sim, nos primeiros dias dos computadores e depois nos primeiros dias dos computadores pessoais, as pessoas escreviam aplicativos em código de máquina.

    
por 09.01.2012 / 16:29
fonte
2

Uma anedota:

Quando aprendi a linguagem assembly, na Apple] [ havia um programa incluído na ROM chamado micro-assembler. Ele fez tradução imediata da instrução de montagem para bytes, conforme você os inseriu. Isso significa que não havia rótulos - se você quiser pular ou carregar, você mesmo teria que calcular os desvios. Foi muito mais fácil do que procurar os layouts de instruções e inserir valores hexadecimais.

Sem dúvida, os montadores reais foram primeiro escritos usando o micro-montador, ou algum outro ambiente não muito completo.

    
por 13.01.2012 / 16:55
fonte