A linguagem de montagem x86 é a família de linguagens de montagem de compatibilidade reversa para a classe de processadores x86, que inclui a série Pentium da Intel e a série Athlon da AMD. Como todas linguagens de montagem, ela utiliza mnemônicas curtas para representar as operações fundamentais que a CPU em um computador pode realizar. Compiladores muitas vezes produzem código de montagem como um passo intermediário ao traduzir um programa de alto nível para código de máquina. Lembrada como uma linguagem de programação, a programação de montagem é especificada à máquina e de baixo nível, com certeza o mais baixo nível possível, adereçando diretamente hardware, também conhecido como metal descoberto. Linguagens de montagens são, portanto, principalmente usadas para aplicações detalhas ou de tempo crítico como inicializadores, núcleos de sistemas operativos, e controladores de dispositivos, assim como para sistemas operativos de tempo real ou pequenos sistemas embarcados, embora seja perfeitamente possível escrever um software aplicativo em um dialeto apropriado (determinado pela escolha do montador) da linguagem de montagem com um montador que compila para a arquitetura alvo.

História

As CPUs Intel 8088 e 8086 era CPUs de 16 bits que tiveram primeiro um conjunto de instruções, que hoje é comumente conhecido como x86, eles eram uma evolução da geração anterior de CPUs de 8 bits como a 8080, herdando muitas características e instruções, estendidas à era 16 bits. A 8088 e 8086 ambas utilizada um barramento de endereços de 20 bits e registros interno de 16 bits, enquanto o 8086 possuía um barramento de endereços de 16 bits, a 8088, criado como uma opção de baixo custo para aplicações embarcadas, possuía um barramento de endereços de 8 bits. A linguagem de montagem x86 cobria diferentes versões das CPUs que seguiram, da Intel; a 80188, 80186, 80286, 80386, 80486, Pentium além de CPUs da AMD e Cyrix como os processadores 5x86 e K6. O termo x86 aplica para qualquer CPU capaz de rodar o código de montagem original (geralmente ele vai rodar pelo menos uma das extensões também).

O conjunto de instruções moderno é um superconjunto das instruções do 8086 e uma série de extensões para este conjunto de instruções que começam com o microprocessador Intel 8008, há compatibilidade reversa praticamente total entre o chipe Intel 8086 até os mais modernos Pentium 4, Intel Core, Core i7, AMD Athlon 64, Opteron, etc., embora certas exceções existam. Na prática é típico utilizar instruições que irão executar qualquer coisa posterior ao Intel 80386 (ou um clone totalmente compatível) ou então qualquer coisa posterior a um Intel Pentium (ou clone compatível), mas nos anos recentes, vários sistemas operativos e aplicativos começaram a exigir processadores mais modernos, pelo menos para obter suporte a extensões específicas como (ex. MMX, 3DNow!, SSE/SSE2/SSE3).

Mnemônicas e opcodes

Cada instrução de montagem x86 é representada por uma mnemônica, que geralmente com um ou mais operadores, traduz para um ou mais bytes, chamados opcode; a instrução NOP traduz para 0x90, por exemplo e a instrução HLT traduz para 0xF4. Há opcodes sem nenhuma mnemônica documentada, que diferentes processadores podem interpretar de maneiras diferentes, um programa usando elas funciona de maneira inconsistente ou até gera exceções em alguns processadores. Em competições de escrita, estes opcodes acabam sendo uma modo de tornar o código menor, mais rápido ou elegante ou apenas para mostrar a profissionalidade do autor.

Sintaxe A linguagem de montagem x86 possui dois ramais de sintaxe: sintaxe Intel, usada originalmente para documentação da plataforma x86, e sintaxe AT&T. Sintaxe Intel é dominante no sistema operativo Microsoft Windows. No mundo Unix/Linux, ambas são usadas pois o GCC suportava apenas a sintaxe AT&T nos primórdios de sua criação. Aqui está um resumo das principais diferenças entre a Sintaxe Intel e a Sintaxe AT&T:

Attribute AT&T Intel Parameter order source comes before the destination destination before source follows that of many program statements ("a=5" is "mov eax, 5") Parameter Size mnemonics are suffixed with a letter indicating the size of the operands (e.g. "q" for qword, "l" for dword, "w" for word, and "b" for byte) derived from the name of the register that is used (e.g. eax, ax, al) Immediate value sigils prefixed with a "$", and registers must be prefixed with a "%" The assembler automatically detects the type of symbols - if they are registers, constants or something else. Effective addresses general syntax DISP(BASE,INDEX,SCALE) Example: movl mem_location(%ebx,%ecx,4), %eax use variables, and need to be in square brackets; additionally, size keywords like 'byte', 'word' or 'dword' have to be used. Example: mov eax, dword [ebx + ecx*4 + mem_location]

A maioria dos montadores x86 usa a sintaxe Intel, incluindo MASM, TASM, NASM, FASM e YASM. GAS suporta ambas sintaxes desde a versão 2.10 através da diretiva .intel_syntax.

Registros

Processadores x86 possuem uma coleção de registros disponíveis para serem usados como armazéns para dados binários. Colectivamente os dados e os endereços de registro são chamados de registros gerais. Cada registro possui um propósito especial além do que eles todos podem fazer.

AX multiplicar/dividir BX registro indicador para MOVE CX registro de contagem para operadores de linha DX endereço de porta para IN e OUT

Além dos registro gerais, adicionalmente há os: IP ponteiro de instrução; FLAGS; registros de segmento (CS, DS, ES, FS, GS, SS) que ativam onde um segmento de 64k começa; registros extra de extensão (MMX, 3DNow!, SSE, etc.).

O registro IP aponta para onde no programa o processador está atualmente executando o seu código. O registro IP não pode ser acessado pelo programador diretamente.

Endereço segmentado A arquitetura x86 em modo real e virtual 8086, usa um processo conhecido como segmentação de endereços de memória, não o modelo de memória plana, usado em muitos outros ambientes. Segmentação envolve a composição de um endereço de memória de duas partes, um segmento e um deslocamento; pontos do segmento até o início de um grupo de 64 KB de endereços, e o deslocamento determina o quão longe desse endereço iniciar o endereço desejado. No endereçamento segmentado, dois registros são necessários para um endereço completo da memória: um para segurar o segmento, a outra para realizar o deslocamento. A fim de traduzir de volta para um endereço de plano, o valor de segmento é deslocado quatro bits à esquerda (o equivalente a multiplicação por 24 ou 16), em seguida, adicionado ao deslocamento para formar o endereço completo, que permite quebrar a barreira de 64k com a escolha inteligente de endereços, endereçar até 1 MB de memória enquanto estiver usando 16 bits, ao invés de registros de 32 bits, embora ele torna a programação muito mais complexa. No modo real, apenas, por exemplo, se DS contém o número hexadecimal 0xDEAD, e DX contém o número 0xCAFE, eles juntos apontariam para o endereço de memória 0xDEAD * + 0x10 = 0xCAFE 0xEB5CE. No modo real o processador pode endereçar até 1.048.576 bytes (1 MB). Isto aplica-se a 20-bits espaço de endereço. Ao combinar valores de deslocamento do segmento encontramos um endereço de 20 bits. O PC original de IBM restringiu programas a 640 KB, mas uma especificação da memória expandida foi usada para executar um esquema do interruptor de banco que caísse fora do uso quando uns sistemas operacionais posteriores, tais como Windows, usaram as escalas de endereço maiores de uns processadores mais novos e executaram seus próprios esquemas da memória virtual. O Modo Protegido, começando com o processador Intel 80286, foi utilizado pelo OS / 2. Várias deficiências, como a impossibilidade de acessar o BIOS, e da incapacidade de voltar ao modo real sem precisar reiniciar o processador. impediram uma utilização generalizada. O 80286 também estava limitado a endereçamento de memória em segmentos de 16 bits, ou seja, apenas 216 bytes (64 kilobytes) podiam ser acessados ao mesmo tempo. Para acessar a funcionalidade estendida do 80286, o sistema operacional deveria definir o processador em modo protegido, permitindo endereçamento de 24 bits e, portanto, 224 bytes de memória (16 megabytes). Ao se referir a um endereço com um segmento e um deslocamento, a notação de segmento: offset é usada, assim, no exemplo acima, o endereço 0xEB5CE plano pode ser escrito como 0xDEAD: 0xCAFE ou como um segmento, e o deslocamento par de registradores; DS: DX.

Registradores de Segmento: CS: Segmento de Código; DS: Segmento de Dados; SS: Segmento de Pilha; ES: Segmento de Dados Extra; FS: Segmento de Dados Extra 2; GS:Segmento de Dados Extra 3;

Registradores de Ponteiros e Índice, usados para armazenar endereços de memória: ESP: Ponteiro de pilha EBP: Ponteiro de base da pilha ESI: Ponteiro de índice fonte (pode servir como registradores de uso geral) EDI: Ponteiro de índice destino (pode servir como registradores de uso geral) EIP: Ponteiro de instrução (contador de programa)

O Intel 80386, apresentou três modos de operação: modo real, modo protegido, e modo virtual. O modo protegido, que estreou no 80.286 foi estendido para permitir o 80386 para endereçar até 4 GB de memória, o novo modo 8086 virtual, (vm86) tornou possível executar um ou mais programas de modo real em um ambiente protegido, que em grande parte imitando modo real, embora alguns programas não eram compatíveis (geralmente como resultado de endereçamento de memória usando truques ou indeterminado op-codes). O modelo de memória plana de 32 bits, do modo protegido, estendida até 80386 pode ser a mudança mais importante da característica para a família de processadores x86, até que a AMD lançou x86-64 em 2003, ajudou a impulsionar a adoção em grande escala do Windows 3.1 (que se baseava em modo protegido), desde que o Windows pode agora executar vários aplicativos simultaneamente, incluindo aplicativos DOS, usando memória virtual e multitarefa simples.

Modo de Execução

Os processadores x86 sustentam cinco modos de operação para o código 86, o modo real, o modo protegido, modo longo, modo 86 virtual, e administração de sistemas, em que algumas instruções estão disponíveis e outras não. Um subgrupo de 16 bits de instruções estão disponíveis no modo real (todos os processadores x86), o modo 16-bit protegido (80286 em diante), V86 (80386 e posteriores) e CEM (Alguns i386SL Intel, i486 e posteriores). Em 32 bits do modo protegido (Intel 80386 em diante), instruções de 32 bits (incluindo as extensões mais tarde) também estão disponíveis, no modo de tempo (a partir de AMD Opteron), instruções de 64 bits, e registra mais, também estão disponíveis. O conjunto de instruções é semelhante em cada modalidade, mas de endereçamento de memória e tamanho da palavra variam, exigindo estratégias de programação diferentes.

Os modos em que o código x86 pode ser executado são:

Modo real (16 bits): Modo Real é caracterizado por um espaço de endereço de 20 bits de memória segmentada, (dando um pouco mais de 1 MB de memória endereçável) e software de acesso ilimitado e direto da memória e endereços de I / O e hardware periférico. Modo Real não oferece suporte para proteção de memória, multitarefa, ou níveis de privilégio de código.

O modo protegido (16 bits e 32 bits): Em computação, de modo protegido, também chamado de modo de endereço virtual protegido, é um modo operacional de x86 compatível com unidades de processamento central (CPU). Ele permite que o software do sistema utilize recursos como memória virtual, paginação, multi-tarefa segura e outros recursos projetados para aumentar o controle de um sistema operacional em relação ao software aplicativo.

Modo longo (64 bits):