O que é assembly? Link para o cabeçalho
Assembly é uma linguagem de programação de baixo nivel, ela é escrita para se comunicar diretamente com o hardware do processador. Ao contrário das linguagens de alto nivel, como o famoso python, o assembly opera próximo ao código de máquina, o famoso binário! Cada instrução em assembly geralmente representa uma única operação da CPU, como mover dados entre registradores, realizar operações aritméticas ou controlar o fluxo de execução.
Assembly não é universal!! Ele depende diretamente da arquitetura do processador. Por exemplo, um código em assembly feito para processadores x86 não funcionará em uma arquitetura ARM, isso significa que aprender assembly é também aprender sobre a estrutura interna e o funcionamento da cpu em questão. Então, se você quer aprender assembly, papers como o do nosso membro voiiid podem te ajudar bastante nessa jornada! https://pwnbuffer.org/en/posts/void/x86/
Aqui está uma tabela dos registradores x86 e x86_64, mostrando EAX, EBX… e seus equivalentes, RAX, RBX…

Assembly é uma linguagem bem antiga, surgindo em meados dos anos 50, mas mesmo assim, ela é muito relevante, mas, por que ainda é relevante?
Simplesmente porque ela é uma ferramenta essencial em várias áreas da computação, como na engenharia reversa, para analisar binários e entender softwares sem acesso ao código fonte.
Assembly NÃO é uma linguagem genérica! Ela reflete a arquitetura do processador que está sendo usado. Isso significa que os registradores, instruçõees e modos de endereçamento variam entre arquiteturas como x86, x86_64, ARM & MIPS. Aprender assembly é aprender a linguagem interna do processador. Essa ligação direta torna assembly indnispensável para compreender como um código em C se transforma em instruções binárias e como o sistema realmente executa cada linha do código. Ele revela o que está “por baixo do tapete”.
Arquitetura x86/x86_64 Link para o cabeçalho
A principal diferença entre as arquiteturas de 32 bits e de 64 bits está na largura dos registradores, ou seja, na quantidade de dados que o processador pode manipular de uma vez:
- 32 bits –> os registradores e os endereços são limitados a 4GB
- 64 bits –> os registradores e os endereços podem acessar até 16 exabytes, teoricamente (2⁶⁴) embora o limite na pratica seja muito menor
Além do aumento da capacidade, a arquitetura x86_64 traz mais registradores, o que melhora o desempenho e reduz a necessidade de acessar a memória constantemente.
Registradores principais Link para o cabeçalho
x86 Link para o cabeçalho
- EAX, EBX, ECX, EDX –> registradores gerais
- ESP –> stack pointer
- EBP –> base pointer
- ESI/EDI –> cópia & manipulação de memória
Cada registrador tem 32 bits (ou seja, 4 bytes) eles também podem ser acessados parcialmente como AX, AH, AL (16 e 8 bits)
x86_64 Link para o cabeçalho
- todos os registradores de 32 bits foram expandidos: EAX –> RAX, EBX –> RBX e etc..
- adição de novos registradores R8 até R15
- stack pointer e base pointer também mudaram: ESP –> RSP & EBP –> RBP
Cada registrador agora armazena 64 bits (8 bytes) e também pode ser acessado em porções, por exemplo: RAX (64 bits), EAX (32 bits), AX (16 bits), AL (8 bits)
Estrutura de um Programa em Assembly Link para o cabeçalho
Um programa em assembly geralmente é dividido em seções que organizam os dados e o código, por exemplo:
.data
–> onde ficam os dados inicializados (como as strings e variáveis com valor definido).bss
–> para dados não inicializados (variáveis reservadas, mas sem valor inicial).text
–> contém o código executável do programa
section .data
msg db "Olá, Mundo!", 0Ah
section .text
global _start
_start:
;sys write
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, 13
int 0x80
;sys exit
mov eax, 1
xor ebx, ebx
int 0x80
Esse exemplo usa chamadas de sistema do linux com int 0x80
, válidas em sistemas de 32 bits. Ele simplesmente imprime "Olá, Mundo!"
no terminal e depois finaliza o programa.
Conceitos Chave Link para o cabeçalho
-
Intruções comuns:
-
MOV
–> move dados entre registradores e memória -
ADD
,SUB
–> soma e subtração -
CMP
–> compara valores (usado antes deJMP
) -
JMP
,JE
,JNE
, etc. –> saltos (condicionais ou não) -
Flags:
ZF
(Zero Flag) –> setada se o resultado for zeroCF
(Carry Flag) –> indica overflow em operações sem sinalSF
(Sign Flag) –> indica se o resultado é negativoOF
(Overflow Flag) –> indica overflow em operações com sinal
-
Stack:
PUSH
–> coloca um valor na stackPOP
–> remove o topo da stackCALL
–> empilha o endereço de retorno e salta para a funçãoRET
–> retorna da função para o endereço salvo
section .data
msg db "exec func!", 0Ah
len equ $ - msg
section .text
global _start
_start:
call message
mov eax, 1
xor ebx, ebx
int 0x80
message:
push eax
push ebx
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, len
int 0x80
pop ebx
pop eax
ret
Nesse exemplo, o programa chama a função message
usando CALL
, que automaticamente faz um PUSH
do endereço de retorno.
Dentro da função:
- Os registradores
eax
&ebx
são salvos comPUSH
- A syscall
write
imprime"exec func!"
- Depois,
POP
restaura os registradores originais - E o
RET
volta para depois doCALL
, onde o programa continua
Calling Conventions Link para o cabeçalho
As calling conventions definem como funções recebem argumentos, retornam valores e manipulam a stack, são essas as regras que garantem compatibilidade entre codigos assembly e outras linguagens como C!
Main Conventions Link para o cabeçalho
-
cdecl
–> C declaration, comum no linux 32 bits- argumentos: passados na stack, da direita pra esquerda
- responsável por limpar a stack: quem chama a função
caller
- retorno: via
EAX
- muito usada com: GCC, linguagens C/C++
-
stdcall
–> Comum no windows 32 bits- argumentos: passados na stack, da direita pra esquerda
- responsável por limpar a stack: a função chamada
callee
- retorno: via
EAX
- muito usada com: APIs do windows
-
sycv
–> System V AMD64 ABI, padrão no linux 64 bits- argumentos: via registradores, nesta ordem:
RDI
,RSI
,RDX
,RCX
,R8
,R9
- extras vão para a stack
- retorno: via
RAX
- responsável por salvar registradores temporários:
caller
- argumentos: via registradores, nesta ordem:
Resumão visual: Link para o cabeçalho
Convenção | Plataforma | Argumentos via | Retorno | Quem limpa a pilha |
---|---|---|---|---|
cdecl |
Linux 32bit | Pilha (dir → esq) | EAX | Quem chama |
stdcall |
Windows 32b | Pilha (dir → esq) | EAX | Função chamada |
sysv |
Linux 64bit | Registradores + pilha | RAX | Quem chama |
Bom, chegamos ao final de mais um paper, muito obrigado por ler até aqui! Espero ter te ajudado em algo, e segue as fontes que utilizei para criar este artigo! ;)
Fontes usadas para a construção deste artigo: