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

Estou confuso sobre o código da máquina e o código nativo no contexto das línguas.net.

Qual é a diferença entre eles? São iguais?

Author: Peter Cordes, 2010-08-08

4 answers

Os termos são realmente um pouco confusos, porque às vezes são usados de forma inconsistente.

Código da máquina: Este é o mais bem definido. É o código que usa as instruções byte-code que o seu processador (a peça física de metal que faz o trabalho real) entende e executa diretamente. Todos os outros códigos devem ser traduzidos ou transformados em Código da máquina antes que a sua máquina possa executá-lo.

Código nativo: este termo é por vezes usado em locais onde o código da máquina (ver acima) é significado. No entanto, também é por vezes usado para significar Código não gerido (ver abaixo).

Código não gerido e código gerido: O Código não gerido refere-se a um código escrito numa linguagem de programação como C ou C++, que é compilado directamente em Código da máquina. Contrasta com o código gerido , que está escrito em C#, VB.NET, Java, ou similar, e executado em um ambiente virtual (como . NET ou o JavaVM) que tipo de" simula " um processador em software. A principal diferença é que o código gerenciado "gerencia" os recursos (principalmente a alocação de memória) para você, empregando coleta de lixo e mantendo as referências a objetos opacos. o código não gerido é o tipo de código que requer que você alocar manualmente e des-alocar memória, às vezes causando vazamentos de memória (quando você se esquece de Des-alocar) e às vezes falhas de segmentação (quando você Des-alocar também logo). não-gerenciado {[7] } também geralmente implica que não existem verificações de tempo de execução para erros comuns, tais como a dereferenciação de ponto nulo ou o transbordamento de limites de array.

Estritamente falando, as linguagens mais dinâmicas - como Perl, Python, PHP e Ruby - são também o código gerido. No entanto, eles não são comumente descritos como tal, o que mostra que o código gerenciado é na verdade um termo de marketing para os ambientes de programação comercial realmente grandes, graves (. NET e Hipoteca).

Código de montagem: este termo geralmente se refere ao tipo de código fonte que as pessoas escrevem quando realmente querem escrever byte-code. Um assembler é um programa que transforma este código-fonte em código-byte real. Não é um compilador porque a transformação é 1 para 1. No entanto, o termo é ambíguo quanto ao tipo de código byte usado: ele pode ser gerenciado ou não gerido. Se não for gerido, o byte-code resultante é o código da máquina . Se for gerido, ele resulta no código byte usado nos bastidores por um ambiente virtual como .NET. Managed code (por exemplo, C#, Java) é compilado nesta linguagem de código byte especial, que no caso do.NET é chamado Common Intermediate Language (CIL) e em Java é chamado byte-code Java. Normalmente, há pouca necessidade de o programador comum acessar este código ou escrever diretamente nesta linguagem, mas quando as pessoas o fazem, muitas vezes se referem a ele como Código de montagem porque eles usam um montador para transformá-lo em código byte.

 122
Author: Timwi, 2010-08-08 12:35:22

O que você vê quando usa depurar + Windows + desmontar ao depurar um programa C# é um bom guia para estes Termos. Aqui está uma versão anotada dele quando eu compilar um programa 'hello world' escrito em C# na configuração de lançamento com JIT optimization habilitado:

        static void Main(string[] args) {
            Console.WriteLine("Hello world");
00000000 55                push        ebp                           ; save stack frame pointer
00000001 8B EC             mov         ebp,esp                       ; setup current frame
00000003 E8 30 BE 03 6F    call        6F03BE38                      ; Console.Out property getter
00000008 8B C8             mov         ecx,eax                       ; setup "this"
0000000a 8B 15 88 20 BD 02 mov         edx,dword ptr ds:[02BD2088h]  ; arg = "Hello world"
00000010 8B 01             mov         eax,dword ptr [ecx]           ; TextWriter reference
00000012 FF 90 D8 00 00 00 call        dword ptr [eax+000000D8h]     ; TextWriter.WriteLine()
00000018 5D                pop         ebp                           ; restore stack frame pointer
        }
00000019 C3                ret                                       ; done, return

Carregue com o botão direito na janela e assinale o "mostrar os Bytes de código" para obter uma visualização semelhante.

A coluna à esquerda é o código da máquina. Seu valor é falsificado pelo depurador, o código é realmente localizado noutro lugar. Mas isso pode ser em qualquer lugar, dependendo da localização selecionada pelo compilador JIT, então o depurador apenas começa a numeração de endereços a partir de 0 no início do método.

A segunda coluna é o código da máquina. Os 1s e 0s reais que a CPU executa. O código da máquina, como aqui, é comumente exibido em hex. Ilustrative maybe is that 0x8B selects the MOV instruction, the additional bytes are there to tell the CPU exactly what needs to be moved. Observe também os dois sabores da instrução de chamada, 0xE8 é a chamada direta, 0xFF é a instrução de chamada indireta.

A terceira coluna é o código de montagem. Montagem é uma linguagem simples, projetada para facilitar a escrita de código de máquina. Ele se compara A C# sendo compilado para IL. O compilador usado para traduzir o código de montagem é chamado de "montador". Você provavelmente tem o Microsoft assembler em sua máquina, seu nome executável é ml.exe, ml64.exe para a versão de 64 bits. Existem duas versões comuns de linguagens de montagem em uso. O que vês é aquele que a inteligência e a AMD usam. No mundo de código aberto, a montagem na notação AT&T é comum. A sintaxe da linguagem é fortemente dependente do tipo de CPU para o qual é escrito, a linguagem de montagem para um PowerPC é muito diferente.

Está bem, isso aborda dois dos termos da tua pergunta. "Código nativo" é um termo difuso, não é raramente usado para descrever o código em uma linguagem não gerenciada. Instrutivo talvez seja ver que tipo de código de máquina é gerado por um compilador C. Esta é a versão "hello world" em C:
int _tmain(int argc, _TCHAR* argv[])
{
00401010 55               push        ebp  
00401011 8B EC            mov         ebp,esp 
    printf("Hello world");
00401013 68 6C 6C 45 00   push        offset ___xt_z+128h (456C6Ch) 
00401018 E8 13 00 00 00   call        printf (401030h) 
0040101D 83 C4 04         add         esp,4 
    return 0;
00401020 33 C0            xor         eax,eax 
}
00401022 5D               pop         ebp  
00401023 C3               ret   

Eu não anotei, principalmente porque é tão similar ao código da máquina gerado pelo programa C#. A chamada de função printf() é bastante diferente da consola.WriteLine () call but everything else is about the same. Observe também que o depurador está agora gerando o endereço de código da máquina real e que é um pouco mais inteligente sobre simbolo. Um efeito colateral de gerar a informação de depuração depois de gerar o código da máquina, como os compiladores não geridos costumam fazer. Eu também devo mencionar que eu desliguei algumas opções de otimização de código da máquina para fazer o código da máquina parecer semelhante. Compiladores C / C++ têm muito mais tempo disponível para otimizar o código, o resultado é muitas vezes difícil de interpretar. E muito difícil de depurar.

O ponto chave aqui é que existem muito poucas diferenças entre o código da máquina gerado a partir de um linguagem gerenciada pelo compilador JIT e código de máquina gerado por um compilador de código nativo. O que é a principal razão pela qual a linguagem C# pode ser competitiva com um compilador de código nativo. A única diferença real entre eles são as chamadas de função de suporte. Muitos dos quais são implementados no CLR. E isso gira em torno do coletor de lixo.

 39
Author: Hans Passant, 2010-08-08 13:28:20

O código nativo e o código da máquina são a mesma coisa -- os bytes reais que a CPU executa.

O código de montagem tem dois significados: um é o código da máquina traduzido em uma forma mais legível para o homem (com os bytes para as instruções traduzidas em mnemônicas curtas como "JMP" (que "salta" para outro ponto no código). O outro é o Il bytecode (bytes de instrução que compiladores como C# ou VB geram, que acabará por ser traduzido em código de máquina eventualmente, mas ainda não são) que vive em um DLL ou EXE.

 5
Author: cHao, 2010-08-08 12:04:06

In. net, os conjuntos contêm MS Intermediate Language code (MSIL, às vezes CIL).
É como um código de máquina de "alto nível".

Quando carregado, o MSIL é compilado pelocompilador JIT em código nativo (código da máquina Intel x86 ou x64).

 2
Author: Henk Holterman, 2010-08-08 12:02:04