Organização de Programas em Assembly NASM
Programas Assembly geralmente não se limitam a um único arquivo. Dividir o código em módulos facilita o desenvolvimento, a manutenção e o reuso de funções em outros projetos.
O NASM oferece duas principais formas de estruturar programas compostos por múltiplos arquivos:
- Inclusão direta de arquivos com
%INCLUDE - Compilação e ligação separadas (módulos externos com
globaleextern)
1. Inclusão de Arquivos com %INCLUDE
Esse método insere o conteúdo de outro arquivo diretamente no ponto onde a diretiva aparece, antes da montagem.
Funciona de forma semelhante à diretiva #include da linguagem C.
Exemplo: arquivo sum.asm
section .text
; Função que retorna a soma de dois números
; Parâmetros:
; rdi - primeiro número
; rsi - segundo número
; Resultado: rax
sum:
mov rax, rdi
add rax, rsi
retA função recebe dois valores pelos registradores rdi e rsi e retorna o resultado em rax.
Arquivo principal hello.asm (Linux)
global _start
section .text
%INCLUDE "sum.asm"
_start:
mov rdi, 33
mov rsi, 44
call sum
mov rdi, rax ; coloca o resultado em RDI para conferência
mov rax, 60
syscallA diretiva:
%INCLUDE "sum.asm"insere literalmente o conteúdo do arquivo sum.asm nesse ponto do código.
Compilação
nasm -f elf64 hello.asm -o hello.o ld hello.o -o hello ./hello echo $?
Saída esperada:
77
Exemplo (Windows)
global _start
section .text
%INCLUDE "sum.asm"
_start:
mov rdi, 33
mov rsi, 44
call sum
ret2. Compilação e Ligação Separadas
O segundo método é mais modular e profissional: cada módulo é compilado separadamente em um arquivo objeto (.o) e depois todos são ligados em um único executável.
Etapa 1 – Arquivo sum.asm
global sum ; torna a função acessível a outros módulos
section .text
; Função que retorna a soma de dois números
; Parâmetros:
; rdi - primeiro número
; rsi - segundo número
; Resultado: rax
sum:
mov rax, rdi
add rax, rsi
retA diretiva global sum indica que a função deve ficar visível externamente — outros módulos poderão chamá-la.
Se não for declarada como global, a função seria apenas interna ao módulo.
Etapa 2 – Arquivo hello.asm
global _start
extern sum ; indica que a função sum está em outro módulo
section .text
_start:
mov rdi, 33
mov rsi, 44
call sum
mov rdi, rax
mov rax, 60
syscallA diretiva extern sum declara que o símbolo sum existe, mas será resolvido apenas na fase de linkagem.
Essas duas diretivas — global e extern — informam ao montador e ao vinculador quais símbolos serão exportados e quais serão importados de outros módulos.
Etapa 3 – Compilação e Linkagem
Linux:
nasm -f elf64 sum.asm -o sum.o nasm -f elf64 hello.asm -o hello.o ld hello.o sum.o -o hello ./hello echo $?
Saída:
77
Explicação dos comandos:
- Cada comando
nasmgera um arquivo objeto (.o). - O comando
ldjunta (linka) os módulos em um único executável. - O comando
echo $?exibe o valor retornado no registradorrax, interpretado pelo sistema como código de saída.
Compilação (Windows)
O mesmo processo é válido, apenas mudando o formato de saída e o vinculador utilizado:
nasm -f win64 sum.asm -o sum.obj nasm -f win64 hello.asm -o hello.obj link hello.obj sum.obj /SUBSYSTEM:CONSOLE /OUT:hello.exe
Comparativo entre os Métodos
| Método | Vantagens | Desvantagens |
|---|---|---|
%INCLUDE | Simples e direto para pequenos projetos | Aumenta o tamanho do código; não há separação real de módulos |
global + extern | Modularidade, reuso, linkagem separada, ideal para projetos grandes | Exige duas etapas (compilação + linkagem) e controle explícito de símbolos |
Resumo
%INCLUDEinsere o conteúdo de outro arquivo no momento da montagem — útil para pequenos programas.globaltorna símbolos (funções, variáveis, constantes) visíveis externamente.externdeclara símbolos externos, resolvidos durante a linkagem.- A compilação separada permite dividir o programa em módulos independentes, facilitando manutenção e reutilização.