Pular para conteúdo

Assembly x86

Atualmente você já aprendeu vários dos conceitos que serão utilizados no Assembly, como:

  • Linguagem de Máquina
  • Instrução
  • Palavra
  • Arquitetura de 32 e 64 bits (ou tamanho da palavra)
  • Registrador
  • Memória RAM.
  • Stack e Heap.

Tendo aprendido isso, agora é só entender as diretrizes e regras para entender e construir programas em ASM. Uma boa leitura é o glossário gratuito da Mente Binária.

Veremos a linguagem de máquina e montagem CISC dos processadores Intel, chamado de x86. Ele foi escolhido porque é a arquitetura mais utilizada para computadores pessoais Windows, em que boa parte dos malwares está alocada.

Um exemplo de código x86 é

mov EAX, 2
add EAX, 3
  • Cada linha representa uma instrução.
  • EAX é um registrador de 32 bits e de uso geral.
  • A operação mov recebe dois operandos, o primeiro é um registrador que irá receber um valor e o segundo é um valor constante que será movido ao registrador.

  • A operação add recebe dois operandos. O primeiro é um registrador que soma seu valor atual com o número no segundo operando. O resultado é guardado no mesmo registrador.

O código anterior pode ser entendido dessa forma:

EAX = 2
EAX = EAX + 3

Cada linha representa uma instrução e normalmente se faz um comentário para cada instrução em ASM indicando o que ela significa. Dessa forma, ficaria assim:

mov EAX, 2 # EAX = 2
add EAX, 3 # EAX = EAX + 3

Tudo em uma linha após um hashtag (#) é ignorado pelo assembler.

Breve história do x86

A linguagem de montagem x86 foi criada para a família de processadores x86, sendo o primeiro o Intel 8086 de 16 bits. Várias empresas participaram da criação e atualização da linguagem incluindo a AMD. Por falar em atualização, a linguagem já foi atualizada diversas vezes, mas sempre tenta manter sua retrocompatibilidade com os sistemas anteriores.

Versões da ISA do x86

  • IA-16 (16 bits)
  • IA-32 (32 bits)
  • IA-64 (64 bits)

Registradores

Uso Geral

No Intel 8086, de 16 bits, foram criados 8 registradores de uso geral de 16 bits:

Notação Título Significado
AX Acumulador Normalmente recebe o resultado de operações
BX Base Normalmente seu conteúdo é interpretado como endereço de memória e usado como enreço inicial/base para alguma operação
CX Contador Normalmente recebe a quantidade de repetições de um loop
DX Data Normalmente é usado como entrada e saída de operações de portas físicas
SP Stack Pointer Guarda o endereço de memória do topo da stack
BP Base Pointer Guarda o enredeço de memória inicial do escopo de memória em que o programa está
SI Start Index Guarda o endereço base de uma string
DI Destination Index Guarda o endereço de destino em que uma string após uma operação

Além disso, o x86 também lhe permite manipular 8 bits dos registradores AX a até DX. Para o AX, podemos escrever AH para nos referimos aos 8 bits mais significativos do registrador AX. Da mesma forma, ao escrever AL, referimo-nos aos 8 bits menos significativos do registrador. O mesmo padrão existe para cada um dos registradores de uso geral.

Com a implementação do Intel i386, a palavra da arquitetura seria de 32 bits e portanto seria conveniente que o x86 oferecesse registradores de x86 para facilitar as operações. Assim foram criados os Registradores de Uso Geral Extendidos. Eles são os mesmos, mas com prefixo "E". Assim sendo EAX, EBX, ECX, EDX, ESP, EBP, ESI e EDI.

O i386 possui somente registradores de 32 bits, mas as chamadas aos registradores de 16 bits continuam funcionando devido a retrocompatibilidade. O i386 converte as chamadas aos registradores de 16 bits em menções aos 16 bits menos significativos dos registradores de 32 bits correspondentes. Veja a imagem:

Registradores de Uso Geral

O mesmo padrão se manteu para os i686 (64 bits). Registradores de 64 bits foram apelidados com o prefixo "R". Além disso, tambem podemos acessar os bytes menos significativos de todos os registradores de 64 bits adicionando o sufixo: - "B" (de byte) para o 8 bits menos significativo. - "W" (de word) para os 16 bits menos significativos. - "D" (de double word) para os 32 bits menos significativos.

Óbvio, existem mais detalhes, mas eles não serão abordados aqui.