Recursos para aprender a programar em código de máquina? [fechadas]

24

Sou estudante, aprendendo a programar e adorando, de Java a C ++ e até C. Movi-me de volta para os barebones e pensei em ir mais longe na Assembly.

Mas, para minha surpresa, muitas pessoas disseram que não é tão rápido quanto C e não adianta. Eles sugeriram aprender como programar um kernel ou escrever um compilador C. Meu sonho é aprender a programar em binário (código de máquina) ou talvez programar bare metal (programar micro-controlador fisicamente) ou escrever bios ou gerenciadores de inicialização ou algo dessa natureza.

A única coisa possível que ouvi depois de tanta pesquisa é que um editor hexadecimal é a coisa mais próxima da linguagem de máquina que pude encontrar nesta época e época. Existem outras coisas que eu não conheço? Existem recursos para aprender a programar em código de máquina? De preferência em um microcontrolador / microprocessador de 8 bits.

Essa pergunta é semelhante à minha, mas estou interessado no aprendizado prático primeiro e depois na compreensão da teoria.

Ás de Espadas
fonte
2
Qual é exatamente o problema aqui? Se você está perguntando se é possível codificar no código da máquina, a resposta provavelmente é "sim". Se você está pedindo tutoriais, então a) deixe claro que é a sua pergunta, mas b) não é uma pergunta construtiva.
ChrisF
6
C não é suficientemente metal?
Tom Squires
6
Eu program bare metalsempre que chuto minha caixa de servidores. Faz maravilhas!
precisa
7
Já pensou em ir ainda mais longe? Hackear sua própria CPU: opencores.org
SK-logic
3
@ SK-logic, sim, a programação do código da máquina ficaria insuportável após cerca de 1 hora. Você está certo, uma idéia melhor e mais produtiva é descer para a implementação da CPU. Há também versões virtuais dos 6502 ( visual6502.org ), bem como pessoas que têm ou aspiram a construção CPU utilizando moderna lógica discreta ( bradrodriguez.com/papers/piscedu2.htm )
Angelo

Respostas:

27

As pessoas não programam em código de máquina (a menos que sejam masoquistas). Eles usam (ou desenvolvem) ferramentas para gerar código de máquina (compilador ou montador, incluindo ferramentas de desenvolvimento cruzado) ou talvez bibliotecas que geram código de máquina (LLVM, libjit, GNU lightning, ....). Portanto, recursos sobre geração de código de máquina, compilação, otimizadores e micro-arquiteturas também são relevantes.

E muitas vezes, um bom compilador de otimização gera código de máquina melhor do que você poderia fazer. Você provavelmente não será capaz de escrever um código assembler de 200 linhas melhor do que um bom otimizador.

Se você deseja entender o código da máquina, aprenda a montagem primeiro. É muito próximo ao código da máquina. Use-o com sabedoria, apenas para coisas que você não pode codificar em C (ou em alguma linguagem de nível superior, como Ocaml, Haskell, Common Lisp, Scala). Muitas vezes, uma boa maneira é usar asminstruções (principalmente o recurso de montagem estendida do GCC ) dentro de uma função C. A leitura do código de montagem (gerado por gcc -S -O2 -fverbose-asm) também pode ser útil.

O Linux Assembly HowTo é uma boa coisa para ler.

A arquitetura do conjunto de instruções do processador atual (ou seja, o conjunto de instruções compreendidas pelo chip) é bastante complexa. Os mais comuns são x86 (um PC típico no modo de 32 bits), X86-64 (um PC de mesa no modo de 64 bits), ARM (smartphones, ...), PowerPC etc. Todos eles são bastante complexos (devido ao histórico e à economia). razões). Talvez aprender primeiro um conjunto de instruções hipotéticas como, por exemplo, o MMIX de Knuth, seja mais simples.

Basile Starynkevitch
fonte
8
"As pessoas não programam em C (...). Eles usam linguagens modernas, talvez com back-end em C"
Abyx 20/12/11
Eu definitivamente concordo. E o meu projeto de trabalho atual (MELT, consulte gcc-melt.org ) é uma DSL traduzido para C.
Basile Starynkevitch
Eu adicionei algumas referências aos ISAs
Basile Starynkevitch
6
E aqueles que querem criar e montar? Existem razões para aprender o código da máquina, embora não sejam tão comuns.
Jetti
Eu diria que está aprendendo uma arquitetura de conjunto de instruções (usando os mnemônicos de montagem). Você raramente aprende explicitamente a codificação exata da instrução (por exemplo, que o NOP é 0x90). Você precisa saber disso ao escrever um montador ou um gerador de código de máquina. (Da mesma forma, você raramente precisa aprender de cor a codificação UTF8 do Unicode).
Basile Starynkevitch
13

Como foi dito anteriormente, aprenda Assembly .

Uma linguagem assembly é uma linguagem de programação de baixo nível para computadores, microprocessadores, microcontroladores e outros dispositivos programáveis. Ele implementa uma representação simbólica dos códigos de máquina e outras constantes necessárias para programar uma dada arquitetura da CPU.

Então Assembly é a symbolic representation of machine code.

Agora você pode estar se perguntando "Ok, então como eu aprendo tudo isso?" Estou tão feliz que você perguntou:

  1. Entenda o que é isso. É de nível muito baixo e oferece uma compreensão muito profunda de um computador. Você pode começar com a Wikipedia e depois ler esta pequena passagem .
  2. Aprenda! As melhores leituras são provavelmente The Art of Assembly Language e Assembly Language, passo a passo: programação com Linux
  3. Obtenha codificação!
Dinâmico
fonte
Eu estava lendo esse outro tópico e acho que me deparei com isso: programmers.stackexchange.com/a/82573/43388 algo dessa natureza em que eu poderia encontrar um tutorial? Mas preciso aprender primeiro a montagem para facilitar a transição.
AceofSpades
11
Obrigado, acho que preciso aprender a montar sob demanda popular. +1
AceofSpades
8

Eu sugiro fortemente que você reconsidere seu objetivo e aqui está o porquê:

Eu aprendi a 6502 Assembly Language no microcomputador da BBC (modelo B, 32K). Ele tinha uma implementação BASIC incrível, que incluía um montador de macros. Nós os tínhamos na escola, então eu escrevi todos os tipos de programas maliciosos que faziam coisas como manipulação direta de buffer de tela para fazer um Lemming percorrer cada tela, ao redor da sala (eles estavam em rede) se as máquinas não fossem usadas por 10 minutos . Isso resultou em risadas entre os meus amigos do 7º ano.

Quando comprei um Commodore 64 em casa, soube que ele tinha uma CPU 6510 que também executava a linguagem assembly 6502, mas com alguns extras interessantes. Eu tive que comprar um montador (veio em um cartucho ) e invocar os programas via BASIC. Com grandes visões de escrever um jogo mais vendido, eu finalmente consegui criar várias demos que o hardware de exibição de vídeo com poucos bits registra na interrupção para fazer efeitos interessantes da barra de cores que animavam a música chip descolada. Impressionante, mas não tão útil.

Em seguida, adquiri um Acorn Archimedes A310 que tinha uma CPU ARM2, então usei a mesma implementação BASIC incrível com o macro assembler incorporado que o BBC Micro (mesma herança). Eu consegui montar alguns jogos que um amigo artístico fornecia gráficos, além de algumas demos trippy baseadas em senoides. Ambos eram um trabalho árduo para programar e códigos incorretos podiam derrubar a máquina (acionar acidentalmente o registro de redefinição de hardware, etc.), perdendo tudo se eu não tivesse salvo (em disquete!).

Na Universidade, fui apresentado ao C ++ e, portanto, ao C. Eu pude usá-lo para programar o Sun / Solaris e alguns outros computadores grandes de mainframe. Não tenho idéia de quais arquiteturas de CPU essas máquinas rodavam - nunca precisei usar assembler ou ler o código da máquina, pois as ferramentas C ++ me deram o poder necessário para produzir aplicativos profissionais.

Depois do Uni, trabalhei no Windows e em vários tipos de Unix. C e C ++ trabalharam em todas essas máquinas e, eventualmente, Java também.

Em seguida, trabalhei no Windows e no Dreamcast usando C ++ com DirectX com uma cadeia abrangente de ferramentas para depuração.

Depois, trabalhei com chipsets baseados em ARM para Smart TVs (em 2000). Embora minha experiência com o ARM2 possa ter sido relevante aqui, o trabalho foi baseado em C. Descobri que todo o hardware que eu fiz no Archimedes também poderia ser feito em C usando operações diretas de manipulação de bits. Parte da minha função era migrar a base de código para Windows, Playstation 2, Linux, outros chipsets de TV e móveis. Todas essas plataformas estavam disponíveis com um compilador C (geralmente GCC) e algum nível de API para gravar na máquina subjacente - o mundo incorporado raramente é um O / S do kernel. Eu nunca precisei conhecer o código completo da máquina para qualquer plataforma em particular, além de escrever um gerenciador de inicialização e um mini BIOS, os quais saltaram para o código C na primeira oportunidade disponível (depois de configurar vetores de interceptação,

O próximo trabalho foi trabalhar com C ++, C # e JavaScript no Windows. Nenhum código de máquina.

O trabalho atual está trabalhando com C ++, JavaScript, Python, LUA, HTML e outras linguagens em várias plataformas. Não tenho idéia de qual código de máquina essas plataformas executam, nem preciso saber - o compilador traduz nosso código para o que for necessário. Se travar, eu pego o erro em um depurador ou através de diagnósticos de tempo de execução (exceções, sinais, etc.).

Por diversão, desenvolvo aplicativos iOS no pouco tempo livre que tenho em casa. Ele usa o Objective-C e uma API que funciona em vários chipsets. Aparentemente, eles são baseados em ARM, mas nunca vi nenhum código de máquina no meu desenvolvimento.

Embora seja um exercício fascinante para aprender a linguagem assembly, agora existem ferramentas e idiomas de nível superior que permitem que você seja uma ordem de magnitude (ou duas) mais produtiva.

O número de oportunidades de trabalho disponíveis para um incrível programador de linguagem assembly / código de máquina é minúsculo em comparação com algo como JavaScript, Java, C #, C ++ ou ObjC.

Eu aconselho que você faça disso um hobby / interesse lateral, e não um objetivo principal.

JBRWilkinson
fonte
6
É um hobby. Estou interessado em saber como as coisas funcionam e aprendo a manipulá-las em um nível muito básico, se possível. +1
AceofSpades
6

Minha sugestão? Aprenda o MIPS e saiba como criar um processador MIPS (simples). Na verdade, é mais fácil do que parece.

A vantagem do MIPS sobre algumas das outras arquiteturas é a simplicidade. Você não será pego em muitos detalhes, mas ainda aprenderá todas as grandes idéias necessárias para escrever código em outras arquiteturas.

Coincidentemente, este foi o projeto final para a minha (terceira) aula de introdução ao CS. Se desejar, você pode ler a tarefa e navegar pelas palestras como vídeos ou slides .

Entre outras coisas, que fez a cobertura como o código MIPS se transformou em binário; tivemos que decodificar algum código de máquina (muito simples) nos exames.

Mesmo que você não queira cobrir tudo, a maioria das palestras foi ministrada por um dos palestrantes favoritos dos alunos e é divertida de se assistir.

Tikhon Jelvis
fonte
Muito obrigado pelos links e explicando por onde devo começar. +1
AceofSpades
6

Sou estudante, aprendendo a programar e adorando, de Java a C ++ e até C. Movi-me de volta para os barebones e pensei em ir mais longe na Assembly.

Excelente caminho a percorrer. Meu salto (queda?) De C para Montagem e inferior foi um curso universitário de Organização e Design de Computadores , baseado no livro com o mesmo nome.

Recomendo este livro para os primeiros capítulos sobre montagem básica do MIPS, até a arquitetura de pipelining e memória. Melhor ainda seria fazer um curso sobre o mesmo tema ou encontrar algumas palestras on-line.

Consulte também o MARS MIPS Simulator para sujar as mãos ao escrever um conjunto.

Matt Stephenson
fonte
4

Se você quiser entender como a máquina funciona completamente, por que você não vai para o nível mais baixo possível e segue até onde está (por exemplo, C, C ++)?

Quero dizer com isso: por que você não constrói seu próprio somador de 4 bits com transistores em um circuito (apenas pesquise no Google se estiver procurando instruções / tutoriais)?

Depois disso, construa um computador pequeno com um pouco de RAM e comece a aprender Assembly e escreva um ou dois programas com ele.

Daniel Scocco
fonte
Se o pôster original construir um computador do zero, ele terá que definir (não apenas aprender) sua própria montagem.
Basile Starynkevitch
@daniels Eu entendo o raciocínio aprendendo adicionando bits, o que é realmente baixo nível. +1
AceofSpades
Uma alternativa para construir um computador a partir do zero poderia ser aprender algum processador antigo (e sua linguagem assembly) como o Z80 ou 6502, que ainda é simples o suficiente para ser entendido. Eu acho que existem até emuladores com os quais você pode brincar.
Giorgio
@AceofSpades Uma ótima maneira de construir facilmente CPUs e componentes de CPU (por exemplo, um adicionador) é com redstone no Minecraft, eu recomendaria isso. Comecei a trabalhar em algumas máquinas simples no Minecraft, e isso aumentou minha compreensão da teoria e lógica por trás dos computadores.
Aaron
1

Eu tenho um conjunto de instruções que foi feito para isso, um simulador e alguns tutoriais sobre o básico, uma instrução ou conceito por lição. Basta digitar o programa, executá-lo e aprender o que ele faz, passar para a próxima lição.

http://www.github.com/dwelch67/lsasim

Também tenho simuladores para alguns conjuntos de instruções convencionais. Qualquer um ou todos os quais são bons para aprender a aprender asm (se você realmente acha que precisa aprender x86, aprendê-lo por último e usar um simulador como o que eu bifurei, primeiro o 8088/86 e depois seguir em frente). Aprender contra um simulador tem prós e contras, um dos principais profissionais, especialmente quando se inicia, é que você não trava nada e tem grande visibilidade. Pulando de cabeça em uma plataforma incorporada, microcontrolador etc. para aprender um novo conjunto de instruções, você precisa superar os obstáculos de não poder ver o que está acontecendo, levando a uma longa lista de maneiras de falhar ...

old_timer
fonte
1

O código de Charles Petzold é uma introdução muito boa ao assunto e descreve o processo de construção de um computador, incluindo como construir somadores, contadores e matrizes de RAM, além de introduzir código de máquina e linguagem assembly e sua relação com linguagens de nível superior. Também é uma ótima leitura sobre a história da computação.

E acabei de ler esta pergunta em electronics.stackexchange, que também pode ser útil

br3w5
fonte