Código de montagem vs Código de máquina vs Código de objeto?

227

Qual é a diferença entre código de objeto, código de máquina e código de montagem?

Você pode dar um exemplo visual da diferença deles?

mmcdole
fonte
Também estou curioso para saber de onde veio o nome "código do objeto"? O que a palavra "objeto" deveria significar nela? De alguma forma, está relacionado à programação orientada a objetos ou apenas uma coincidência de nomes?
SasQ
@SasQ: código do objeto .
Jesse Boa
Não estou perguntando sobre o que é um código de objeto, capitão Óbvio. Estou perguntando de onde veio o nome e por que ele é chamado de código "objeto".
precisa saber é o seguinte

Respostas:

296

O código da máquina é um código binário (1 e 0) que pode ser executado diretamente pela CPU. Se você abrir um arquivo de código de máquina em um editor de texto, verá lixo, incluindo caracteres não imprimíveis (não, esses caracteres não imprimíveis;)).

O código do objeto é uma parte do código da máquina que ainda não foi vinculada a um programa completo. É o código de máquina para uma biblioteca ou módulo específico que compõe o produto concluído. Também pode conter espaços reservados ou deslocamentos não encontrados no código de máquina de um programa concluído. O vinculador usará esses espaços reservados e compensações para conectar tudo.

O código de montagem é um código -fonte legível em texto sem formatação e (um pouco) humano que geralmente possui um analógico direto 1: 1 com as instruções da máquina. Isso é feito usando mnemônicos para obter instruções, registros ou outros recursos reais. Os exemplos incluem JMPe MULTpara as instruções de salto e multiplicação da CPU. Diferentemente do código de máquina, a CPU não entende o código de montagem. Você converte o código do assembly em máquina com o uso de um assembler ou compilador , embora geralmente pensemos em compiladores em associação com uma linguagem de programação de alto nível, que são abstraídas ainda mais das instruções da CPU.

Construir um programa completo envolve escrever o código fonte do programa em assembly ou em uma linguagem de nível superior como C ++. O código fonte é montado (para código de montagem) ou compilado (para linguagens de nível superior) para codificar objetos, e módulos individuais são vinculados para se tornar o código de máquina para o programa final. No caso de programas muito simples, a etapa de vinculação pode não ser necessária. Em outros casos, como em um IDE (ambiente de desenvolvimento integrado), o vinculador e o compilador podem ser chamados juntos. Em outros casos, um script de criação ou arquivo de solução complicado pode ser usado para informar ao ambiente como criar o aplicativo final.

Também existem idiomas interpretados que se comportam de maneira diferente. Os idiomas interpretados dependem do código de máquina de um programa especial de intérpretes. No nível básico, um intérprete analisa o código fonte e converte imediatamente os comandos em novo código de máquina e os executa. Os intérpretes modernos, às vezes também chamados de ambiente de tempo de execução ou máquina virtual , são muito mais complicados: avaliar seções inteiras do código-fonte de cada vez, armazenar em cache e otimizar sempre que possível e lidar com tarefas complexas de gerenciamento de memória. Uma linguagem interpretada também pode ser pré-compilada em uma linguagem intermediária ou bytecode de nível inferior, semelhante ao código de montagem.

Joel Coehoorn
fonte
24
+1: agradáveis, mas um pouco simplificadoras resposta - nem todos montagem instruções são traduzidas 1: 1 para instruções de máquina, e objeto arquivos também pode conter outros dados (informações de relocação, tabelas de símbolos, ...)
Christoph
5
Adicionada uma palavra de doninha para sua primeira edição, editada para tornar a segunda mais clara.
Joel Coehoorn
2
@Christoph: você diz "nem todas as instruções de montagem são traduzidas 1: 1 nas instruções da máquina", por favor, dê um exemplo.
Olof Forshell
5
@Olof: arquitecturas RISC, por vezes, proporcionar um conjunto de nível de conjunto de instruções virtuais - por exemplo, MIPS pseudo-instruções ( en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions )
Christoph
3
@ Panzercrisis Nada é adicionado pelo montador. É uma tradução direta do que você escreveu nas instruções reais da máquina. E eu não chamaria o código extra colocado em por compiladores "desnecessário"
Joel Coehoorn
125

As outras respostas deram uma boa descrição da diferença, mas você pediu um visual também. Aqui está um diagrama mostrando que eles viajam do código C para um executável.

Graphics Noob
fonte
3
Acho isso realmente útil, mas está faltando o rótulo de "código Machine"
Alexx Roche
Então, quando está no nível do código executável, isso é equivalente ao código da máquina?
CMCDragonkai
3
No contexto deste diagrama, o "código do objeto" é o código da máquina.
Graphics Noob
5
Na verdade, o código do objeto e o código executável são códigos de máquina. a diferença é que o código do objeto não é o programa concluído. Ele precisa ser combinado com outros códigos da biblioteca / módulo auxiliar, conforme indicado no diagrama, para formar um programa / código executável completo.
okey_on
@okeyxyz: em que nível seria correto dizer que é executado diretamente pelo processador? Depois do montador, depois do vinculador, depois do carregador, depois de convertido em microcontrolador?
Celeritas
49

O código de montagem é uma representação legível por humanos do código de máquina:

mov eax, 77
jmp anywhere

O código da máquina é um código hexadecimal puro:

5F 3A E3 F1

Suponho que você queira dizer código de objeto como em um arquivo de objeto. Essa é uma variante do código de máquina, com uma diferença de que os saltos são meio que parametrizados, para que um vinculador possa preenchê-los.

Um assembler é usado para converter o código do assembly em código de máquina (código do objeto). Um vinculador vincula vários arquivos de objeto (e biblioteca) para gerar um executável.

Certa vez, eu escrevi um programa assembler em hexadecimal puro (nenhum assembler disponível), felizmente, isso estava no antigo e antigo 6502. Mas estou feliz que haja montadores para os códigos de pentium.

Toon Krijthe
fonte
76
Não não não não. Código de máquina não é código hexadecimal. é binário puro. O código hexadecimal é apenas uma representação conveniente do binário.
Breton
56
Se estamos realmente entrando em extremos, não é binário, é uma quantidade de eletricidade armazenada em um circuito. ;-)
Toon Krijthe
17
Sim, claro. Existe uma relação entre o hexidecimal e o que você chamaria de "Código da Máquina", mas não é muito exato dizer que o código da máquina é hexidecimal . É tudo o que estou tentando dizer.
Breton
9
@Breton Nesse sentido, não existe "código hexadecimal", certo? "Código hexadecimal" é apenas uma maneira de visualizar o código da máquina. Você pode visualizar o código da máquina em hexadecimal, binário, octal, decimal ou como desejar. Também nesse sentido, também não há "código binário". Novamente, "código binário" é apenas uma maneira de visualizar o código da máquina.
Utku
9
@Breton O que você diz não faz muito sentido .. Binário é uma forma de representação, assim como hexadecimal. Se não é hexadecimal, também não é binário.
Koray Tugay
18

8B 5D 32 é um código de máquina

mov ebx, [ebp+32h] é montagem

lmylib.socontendo 8B 5D 32é o código do objeto

Quassnoi
fonte
8

Um ponto ainda não mencionado é que existem alguns tipos diferentes de código de montagem. Na forma mais básica, todos os números usados ​​nas instruções devem ser especificados como constantes. Por exemplo:

$ 1902: BD 37 14: LDA $ 1437, X
$ 1905: 85 03: STA $ 03
$ 1907: 85 09: STA $ 09
$ 1909: CA: DEX
Preço: US $ 1902

O bit de código acima, se armazenado no endereço $ 1900 em um cartucho Atari 2600, exibirá várias linhas em cores diferentes buscadas em uma tabela que começa no endereço $ 1437. Em algumas ferramentas, digitar um endereço, junto com a parte mais à direita da linha acima, armazenaria na memória os valores mostrados na coluna do meio e iniciaria a próxima linha com o seguinte endereço. Digitar código nesse formato era muito mais conveniente do que digitar hexadecimal, mas era preciso saber os endereços precisos de tudo.

A maioria dos montadores permite usar endereços simbólicos. O código acima seria escrito mais como:

rainbow_lp:
  lda ColorTbl, x
  sta WSYNC
  sta COLUBK
  dex
  bpl rainbow_lp

O montador ajustaria automaticamente a instrução LDA para que se referisse a qualquer endereço mapeado para o rótulo ColorTbl. O uso desse estilo de montador torna muito mais fácil escrever e editar código do que seria possível se alguém tivesse que digitar manualmente e manter todos os endereços manualmente.

supercat
fonte
1
+1. Mais um ponto adicional: também existem diferentes sintaxes da linguagem assembly , sendo as mais famosas Intel e AT&T .
informatik01
1
@ informatik01: Que tal mnemônicos Intel 8080 vs Zilog Z80? Eu acho que isso é anterior à guerra de sintaxe Intel vs AT&T.
supercat
Sem discutir, acabei de mencionar esse aspecto (sintaxe diferente) e dei um exemplo das duas sintaxes mais populares / conhecidas / famosas.
informatik01
4

Código fonte, Código de montagem, Código de máquina, Código de objeto, Código de bytes, Arquivo executável e Arquivo de biblioteca.

Todos esses termos costumam ser muito confusos para a maioria das pessoas pelo fato de acharem que são mutuamente exclusivos . Veja o diagrama para entender suas relações. A descrição de cada termo é dada abaixo.


Tipos de código


Código fonte

Instruções em linguagem legível por humanos (programação)


Código de alto nível

Instruções escritas em um alto nível (programação) linguagem
por exemplo, programas de C, C ++ e Java


Código de montagem

Instruções escritas em uma linguagem assembly (tipo de linguagem de programação de baixo nível). Como a primeira etapa do processo de compilação, o código de alto nível é convertido nesse formulário. É o código de montagem que está sendo convertido em código de máquina real. Na maioria dos sistemas, essas duas etapas são executadas automaticamente como parte do processo de compilação.
por exemplo, program.asm


Código do objeto

O produto de um processo de compilação. Pode ser na forma de código de máquina ou código de bytes.
por exemplo, arquivo.o


Código da máquina

Instruções em linguagem de máquina.
por exemplo, a.out


Código de bytes

Instrução de forma intermediária que pode ser executada por um intérprete como a JVM.
por exemplo, arquivo de classe Java


Arquivo executável

O produto do processo de vinculação. Eles são códigos de máquina que podem ser executados diretamente pela CPU.
por exemplo, um arquivo .exe.

Observe que, em alguns contextos, um arquivo que contém instruções de código de bytes ou de linguagem de script também pode ser considerado executável.


Arquivo de biblioteca

Algum código é compilado neste formulário por diferentes motivos, como reutilização e posteriormente usado por arquivos executáveis.

Bertram Gilfoyle
fonte
1
Eu diria que nem todo assembly é realmente fonte no sentido mais estrito do código escrito e / ou mantido por humanos. Muitas vezes, é gerado pela máquina a partir da fonte e nunca se destina ao consumo humano (por exemplo, o gcc realmente cria o texto asm que ele alimenta para um montador separado, em vez de ter um montador embutido dentro do cc1executável). Eu acho que o círculo asm deve ficar do lado esquerdo do círculo "fonte", porque alguns asm são apenas asm, não fonte. Nunca é um código de objeto , é claro, mas algumas asm são um passo no caminho da origem para os arquivos de objetos.
Peter Cordes
@ PeterCordes Muito obrigado pelo comentário. Eu não sabia o que você disse sobre o funcionamento do gcc. Receio, no entanto, que concorde plenamente com você. O que quero dizer é que o código fonte é algo escrito usando uma linguagem de programação legível por humanos. Pode ou não ser escrito ou mantido por humanos. Tenho certeza de que você estará ciente dos transcompiladores. Do seu ponto de vista, em qual categoria você colocará o produto desse compilador? Código fonte ou algo mais? Por favor me corrija se eu estiver errado. Comentários adicionais são sempre bem-vindos.
Bertram Gilfoyle
1

O código de montagem é discutido aqui .

"Uma linguagem assembly é uma linguagem de baixo nível para programação de computadores. Implementa uma representação simbólica dos códigos numéricos de máquina e outras constantes necessárias para programar uma arquitetura de CPU específica".

O código da máquina é discutido aqui .

"Código de máquina ou linguagem de máquina é um sistema de instruções e dados executados diretamente pela unidade central de processamento de um computador."

Basicamente, o código do assembler é o idioma e é traduzido para o código do objeto (o código nativo que a CPU executa) por um assembler (análogo a um compilador).

rbrayb
fonte
1

Eu acho que essas são as principais diferenças

  • legibilidade do código
  • controle sobre o que seu código está fazendo

A legibilidade pode melhorar ou substituir o código 6 meses após ter sido criado com pouco esforço, por outro lado, se o desempenho for crítico, convém usar uma linguagem de baixo nível para direcionar o hardware específico que você terá em produção, para obter execução mais rápida.

Hoje, na IMO, os computadores são rápidos o suficiente para permitir que um programador obtenha uma execução rápida com OOP.

Alberto Zaccagni
fonte
1

Assembly é termos descritivos curtos que os humanos podem entender que podem ser traduzidos diretamente no código da máquina que uma CPU realmente usa.

Embora um pouco compreensível pelos humanos, o Assembler ainda é de baixo nível. É preciso muito código para fazer qualquer coisa útil.

Então, em vez disso, usamos linguagens de nível superior, como C, BASIC, FORTAN (OK, eu sei que já me namorei). Quando compilados, estes produzem código de objeto. Os idiomas antigos tinham a linguagem de máquina como código de objeto.

Atualmente, muitas linguagens como JAVA e C # geralmente compilam em um bytecode que não é código de máquina, mas que pode ser facilmente interpretado em tempo de execução para produzir código de máquina.

Jim C
fonte
Seu comentário sobre Java e C # - ambos usam a compilação Just In Time para que os bytecodes não sejam interpretados. O C # (.NET geralmente) é compilado na Linguagem Intermediária (IL), que é então JITed na linguagem de máquina nativa da CPU de destino.
21910 Craig Shearer
-1

Os arquivos de origem dos seus programas são compilados em arquivos de objeto e, em seguida, o vinculador vincula esses arquivos de objeto, produzindo um arquivo executável, incluindo os códigos de máquina da sua arquitetura.

O arquivo de objeto e o arquivo executável envolvem o código de máquina da arquitetura na forma de caracteres imprimíveis e não imprimíveis quando é aberto por um editor de texto.

No entanto, a dicotomia entre os arquivos é que os arquivos de objetos podem conter referências externas não resolvidas (como printf, por exemplo). Portanto, pode ser necessário vincular outros arquivos de objeto. Ou seja, é necessário resolver as referências externas não resolvidas para obter o arquivo executável executável decente vinculando-o a outros arquivos de objeto, como a biblioteca de tempo de execução C / C ++ .

snr
fonte