Como os primeiros compiladores foram feitos?

69

Eu sempre me pergunto isso, e talvez eu precise de uma boa aula de história sobre linguagens de programação. Mas como a maioria dos compiladores atualmente é feita em C, como os primeiros compiladores foram feitos (AKA antes de C) ou todas as linguagens foram interpretadas?

Com isso dito, eu ainda não entendi como até mesmo a primeira linguagem de montagem foi feita, eu entendo o que é a linguagem de montagem, mas não vejo como eles obtiveram a primeira linguagem assembly (como, como eles fazer os primeiros comandos (como mov R21 ) ou w / e configurados para o equivalente binário?

    
por gnat 30.06.2011 / 14:13
fonte

9 respostas

88

Ha, eu fiz isso. Muitas CPUs têm instruções simples, de tamanho fixo, com apenas alguns bytes. Para um CPU simples como o Motorola 6800, por exemplo, você pode colocar todas as suas instruções em uma única folha de papel . Cada instrução teria um opcode de dois bytes associado a ela e argumentos. Você poderia montar manualmente um programa procurando o código de operação de cada instrução. Você então escreveria seu programa em papel , anotando cada instrução com seu opcode correspondente. Depois de escrever o seu programa, você poderia gravar cada opcode em sequência para uma EPROM , que armazenaria seu programa. Conecte a EPROM à CPU com as instruções certas nos endereços corretos e você tem um programa simples de trabalho. E para responder sua próxima pergunta, sim. Foi doloroso (nós fizemos isso no ensino médio). Mas eu tenho que dizer que ligar todos os chips em um computador de 8 bits e escrever um programa manualmente me deu uma compreensão profunda da arquitetura do computador que eu provavelmente não teria conseguido de outra maneira.

Chips mais avançados (como x86) são muito mais difíceis de codificar manualmente, porque eles geralmente têm instruções de tamanho variável. Os processadores VLIW / EPIC, como o Itanium , são praticamente impossíveis de codificar manualmente porque lidar com pacotes de instruções que são otimizadas e montadas por compiladores avançados. Para novas arquiteturas, os programas quase sempre são escritos e montados em outro computador primeiro, depois carregados na nova arquitetura. Na verdade, para empresas como a Intel que realmente constroem CPUs, elas podem executar programas reais em arquiteturas que ainda não existem, executando-as em simuladores. Mas eu discordo ...

Quanto aos compiladores, na sua forma mais simples, eles podem ser pouco mais do que programas de "cortar e colar". Você pode escrever uma "linguagem de alto nível" muito simples, não otimizadora, que apenas agrupa instruções simples de linguagem de montagem sem muito esforço.

Se você quiser um histórico de compiladores e linguagens de programação, sugiro que você GOTO uma história de FORTRAN .

    
por 30.06.2011 / 14:23
fonte
54

Isso é o que bootstrapping do compilador é sobre (já que ninguém mencionou como é chamado =).

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...
    
por 30.06.2011 / 15:59
fonte
15
Em última análise, todos os computadores operam em códigos binários, que são alimentados na CPU. Esses códigos binários são perfeitamente naturais para uma CPU, mas também perfeitamente inúteis para os seres humanos. Uma das primeiras maneiras de escrever um programa foi fazendo furos em cartões. A posição dos furos representava uma posição específica do bit dentro de uma palavra, e a presença ou ausência do furo era interpretada como um zero ou um. Essas cartas foram colocadas na sequência certa em uma caixa e depois inseridas em um leitor de cartões, o que efetivamente as converteu em código binário para a CPU (e sua vida foi efetivamente perdida se você descartasse a caixa).

Obviamente, os primeiros programadores elaboraram os códigos binários um a um e usaram uma máquina para perfurar os cartões. Isso é essencialmente programação em linguagem assembly em suas mãos e joelhos. Depois de ter isso, você pode criar todas as outras coisas a partir dele: um editor de texto simples, um compilador de linguagem de montagem (para converter as instruções de montagem de texto em códigos binários), um vinculador e um carregador. E o resto, como dizem, é história.

    
por 30.06.2011 / 14:25
fonte
7

Um pequeno googling aparece Pedidos iniciais EDSAC do final dos anos 40. Como foi o primeiro montador, provavelmente foi codificado em linguagem de máquina.

Mais tarde vieram os montadores de outras máquinas, como SOAP I e II para o IBM 650. SOAP Eu também provavelmente estava codificado em linguagem de máquina, embora não tenha encontrado a declaração definitiva.

Um pouco mais tarde veio Fortran (tradutor de fórmulas), para o IBM 704. Presumivelmente, foi escrito em assembler para o 704. Um primeiro montador para o 701 é creditado a Nathan Rochester .

Se você quiser ter uma idéia de como programar um computador em linguagem de máquina, confira um dos meus sites favoritos, Computador de retransmissão de Harry Porter .

    
por 30.06.2011 / 15:13
fonte
6

É possível (se tedioso) escrever código de máquina direto. Talvez você escreva o programa no montador em um pedaço de papel e depois o traduza manualmente para as instruções numéricas de código de máquina que você insere na memória da máquina. Você pode até mesmo pular a etapa do montador no papel se tiver memorizado os valores numéricos de todas as instruções do código da máquina - não é incomum naqueles dias, acredite ou não!

Os primeiros computadores foram programados diretamente em binário, alternando os comutadores físicos. Foi uma grande melhoria de produtividade quando o hardware evoluiu para deixar o programador (ou o assistente de entrada de dados) digitar o código em números hexadecimais através de um teclado!

Um montador de software só se tornou relevante quando mais memória ficou disponível (já que o código assembler ocupa mais espaço do que o código de máquina bruto) e o hardware evoluiu para permitir entrada alfanumérica. Então, os primeiros montadores foram escritos diretamente por pessoas fluentes em código de máquina.

Quando você tem um montador, você pode escrever um compilador para uma linguagem de nível superior no assembler.

A história de C tem várias etapas. O primeiro compilador C foi escrito em B (um predecessor de C), que por sua vez foi escrito em BCPL. O BCPL é uma linguagem bastante simples (por exemplo, ele não possui tipos), mas ainda é um passo acima do montador bruto. Assim, você vê como, gradualmente, linguagens mais complexas são construídas em linguagens mais simples e retornam ao assembler. E o próprio C é uma linguagem bem pequena e simples para os padrões de hoje.

Hoje em dia, o primeiro compilador para uma nova linguagem é geralmente escrito em C, mas quando a linguagem atinge uma certa maturidade, ela é reescrita "em si". O primeiro compilador Java foi escrito em C, mas depois reescrito em Java. O primeiro compilador C # foi escrito em C ++, mas recentemente foi reescrito em C #. O compilador / interpretador Python é escrito em C, mas o projeto PyPy é uma tentativa de reescrevê-lo em Python.

No entanto, nem sempre é possível escrever um compilador / interpretador para uma linguagem na própria linguagem. Existe um interpretador JavaScript escrito em JavaScript, mas os compiladores / intérpretes nos navegadores atuais ainda são escritos em C ou C ++ por motivos de desempenho. JavaScript escrito em JavaScript é simplesmente muito lento.

Mas você não precisa usar C como "idioma inicial" para um compilador. O primeiro compilador F # foi escrito em OCaml, que é a outra linguagem que está mais relacionada com F #. Quando o compilador foi concluído, foi reescrito em F #. O primeiro compilador para o Perl 6 foi escrito em Haskell (uma linguagem funcional pura muito diferente do Perl) mas agora tem um compilador escrito em C.

Um caso interessante é Rust, onde o primeiro compilador foi escrito em OCaml (agora ele é reescrito em Rust). Isso é notável porque o OCaml é geralmente considerado um nível mais alto do que o Rust, que é uma linguagem de sistemas mais próxima do metal. Por isso, nem sempre as linguagens de nível superior são implementadas nas linguagens de nível mais baixo, mas também pode ser o contrário.

    
por 05.06.2015 / 14:44
fonte
3

Assumindo que você está começando com um conjunto de instruções e nada mais, você começaria criando um compilador ou compilador mínimo , apenas mal-funcional, que pudesse carregar um arquivo, analisar um mínimo subconjunto do idioma de destino e gerar um arquivo executável como saída, gravando o código de máquina bruto usando um editor hexadecimal ou semelhante.

Você usaria então o compilador ou montador que não funcionava bem para implementar um compilador ou montador um pouco mais capaz que possa reconhecer um subconjunto maior do idioma de destino. Ensaboar, enxaguar, repetir, até ter o produto final.

    
por 30.06.2011 / 15:51
fonte
2

Não é tão difícil, como parece. Na infância;) Fiz algumas desmontagens x86 em mente.

Você nem precisa aprender especialmente. Acontece apenas quando você é capaz de programar em ASM e, em seguida, tentar consertar um binário de terceiros usando desmontadores interativos. Ou ao escrever sua própria proteção com criptografia de código.

Ou seja. às vezes você está migrando mesmo da linguagem para os códigos sem nenhuma surpresa.

    
por 30.06.2011 / 19:30
fonte
1

Os primeiros compiladores foram implementados usando linguagem assembly. E os primeiros montadores foram implementados por programas de codificação em binário ...

Não é há muito tempo que a programação em binário ainda era uma habilidade que as pessoas usavam.

Quando eu era estudante de graduação, eu me lembro de fazer um exercício de programação que implicava escrever um pequeno programa no código de máquina PDP-8 (eu acho), inseri-lo através dos switches do painel frontal e executá-lo. Alguns anos depois, comprei um kit de desenvolvimento de sistema 6502 que tinha um teclado hexadecimal para inserir programas ... e 4k bytes de RAM.

    
por 09.06.2013 / 17:32
fonte
-3

UMA RESPOSTA MUITO SIMPLES Suponha que escrevamos um programa com fio e o armazenemos na ROM. Pode ser considerado como compilador. Então, eu simplesmente quero dizer é que o primeiro compilador foi hardwired. À medida que a tecnologia melhorou, esses compiladores simples foram usados para escrever compiladores de alto nível.

    
por 05.06.2015 / 14:25
fonte