Convenções de assembly da trilha
Uma sintaxe, um montador
Assembly ARM tem duas famílias de sintaxe. A antiga (divided, pré-2005) escrevia as instruções Thumb e ARM de formas diferentes. A atual é a UAL — Unified Assembler Language: o mesmo mnemônico serve para ARM e Thumb, e o montador escolhe a codificação pelo modo (.arm / .thumb). Toda a trilha usa UAL, ligada explicitamente com:
.syntax unifiedO montador é o arm-none-eabi-as do toolchain GNU (arm-none-eabi, instalado no artigo de ambiente). É o mesmo as do GCC — então a sintaxe de diretivas é a do GAS (GNU assembler), não a do armasm da ARM. As diferenças que importam:
| Item | GAS (esta trilha) | armasm (ARM) |
|---|---|---|
| Comentário de linha | @ comentário | ; comentário |
| Comentário de bloco | /* ... */ | — |
| Rótulo | nome: | nome (coluna 1) |
| Constante | .word 0x10 | DCD 0x10 |
| Seção de código | .text | `AREA |
Diretivas do GAS que vão aparecer
Um .s típico da trilha tem esta cara (armbox/testdata/hello.s):
.arch armv5te @ arquitetura alvo (afeta quais instruções são aceitas)
.arm @ montar em estado ARM (32 bits). Alternativa: .thumb
.text @ o que vem abaixo vai para a seção de código
.global _start @ exporta o símbolo _start (o linker precisa dele)
_start: @ um rótulo = um endereço
mov r0, #1
svc #0
msg:
.ascii "hello from a real ELF\n" @ bytes crus na seção atual
msg_end:| Diretiva | O que faz |
|---|---|
.arch <nome> | Define a arquitetura alvo (armv4t, armv5te, armv6k, armv7-a, ...). Instrução fora do alvo → erro de montagem |
.arm / .thumb | Seleciona o estado; muda a largura e a codificação das instruções |
.syntax unified | Liga a UAL (recomendado sempre) |
.text / .data / .bss | Seção de código / dados inicializados / dados zerados |
.global <sym> | Torna o símbolo visível para o linker |
.word / .hword / .byte | Emite 4 / 2 / 1 bytes literais |
.ascii / .asciz | String sem / com terminador NUL |
.align n / .balign n | Alinha o próximo dado a 2^n / n bytes |
.equ NOME, valor | Constante de montagem (sem custo em runtime) |
Anatomia de um mnemônico
O formato geral de uma instrução de processamento de dados é:
<mnemônico>{<cond>}{S} Rd, Rn, <Operand2>{cond}— sufixo de condição (EQ,NE,GE,LT, ...). Quase toda instrução ARM pode ser condicional; sem sufixo, éAL(always).{S}— se presente, a instrução atualiza as flags N/Z/C/V doCPSR.ADDnão mexe nas flags;ADDSmexe.Operand2— um imediato (#42), um registrador (r3) ou um registrador deslocado (r3, LSL #2).
Imediatos levam #: mov r0, #1. Registradores são r0–r15 (com apelidos sp = r13, lr = r14, pc = r15).
Como os listings são apresentados
Ao longo da trilha, código aparece de três formas:
1. O fonte comentado — o .s que você escreve, com @ explicando a intenção.
2. A desmontagem do objdump -d — o que a máquina realmente executa:
Cada linha é endereço: bytes da codificação mnemônico desmontado. A coluna do meio (e3b00005, e2500001, ...) é a instrução de 32 bits em hexadecimal, little-endian no arquivo mas mostrada aqui já na ordem lógica. Decodificar essa coluna à mão é o módulo 2.
3. Sessões de depuração — trechos de gdb mostrando registradores e flags mudando instrução a instrução (padrão do artigo de GDB).
O que esse exemplo já ensina
Dois detalhes do listing acima:
ldr r1, =0x1000sumiu. No fonte estava a pseudo-instruçãoldr r1, =0x1000; o montador viu que0x1000cabe num imediato codificável e trocou pormov r1, #4096. Pseudo-instruções (ldr Rd, =const,adr,nop) são conveniências do montador — não existem no binário.addne r1, r1, #4temcond = NE. A codificação12811004começa com o nibble1(condiçãoNE); a versão incondicional (add) começaria come(AL). É a predicação em ação: a instrução ocupa espaço e tempo, mas só tem efeito seZ == 0. O artigo de flags explora isso.
Comandos do toolchain
| Comando | O que faz |
|---|---|
arm-none-eabi-as -march=armv5te -o x.o x.s | Monta x.s → objeto x.o |
arm-none-eabi-ld -Ttext=0x10000 -o x.elf x.o | Liga x.o → executável x.elf, código em 0x10000 |
arm-none-eabi-gcc -nostdlib -o x.elf x.s | Monta e liga em um passo (sem libc) |
arm-none-eabi-objdump -d x.elf | Desmonta a seção de código |
arm-none-eabi-objdump -s -j .data x.elf | Dump hexadecimal de uma seção |
arm-none-eabi-objcopy -O binary x.elf x.bin | Extrai só os bytes (sem cabeçalho ELF) |
Próximo passo
Com a notação combinada, o módulo 1 entra nos fundamentos: o banco de registradores, o CPSR e a diferença entre ARM e Thumb.
Trilha: Curso de Arquitetura ARM · Módulo 0, lição 3.