← Voltar aos artigosCriando um executável ARM e rodando no arm-box

Criando um executável ARM e rodando no arm-box

Neste primeiro artigo prático do nosso curso de arquitetura ARM, você vai escrever um programa em assembly ARM do zero, montá-lo em um executável ELF real e rodá-lo no arm-box — o runner Linux user-mode construído sobre o arm-jitter. No final, você verá hello from a real ELF impresso por um núcleo ARM emulado em Java.

O que é o arm-box

O arm-box é um runner de binários ARM 32-bit no estilo do qemu-arm. Ele carrega um ELF estático, monta a pilha no formato ABI do Linux, mapeia os kuser helpers do kernel ARM e traduz as syscalls EABI para o sistema hospedeiro. O pulo do gato: a CPU que executa esse binário é o JIT do arm-jitter (por padrão ARMV5TE), então tudo que roda aqui está exercitando de verdade o decodificador, a IR e o backend de código que estudaremos ao longo do curso.

Pré-requisitos

  • JDK 25 (recomendo o JBR) e Maven.
  • Toolchain ARM bare-metal: arm-none-eabi-as / arm-none-eabi-ld (vem no devkitARM). O arm-box usa -nostdlib, então não precisa de libc.
  • O próprio arm-box: git clone https://github.com/vitorsilverio/armbox && cd armbox && mvn package.

Sem toolchain? Os testes de integração do arm-box montam ELFs sintéticos em memória, então mvn test funciona mesmo sem compilador ARM instalado. Mas para acompanhar este tutorial, o as/ld faz diferença.

O programa em assembly

Vamos escrever um "hello world" usando syscalls cruas da ABI EABI do Linux (sem libc). A convenção é simples: o número da syscall vai em r7, os argumentos em r0r3 (e r4r6 quando precisam), e a chamada é feita com svc #0.

.syntax unified
.text
.global _start

_start:
    @ write(1, msg, msg_len)  -- fd=stdout, buffer, tamanho
    mov   r0, #1            @ fd = 1 (stdout)
    ldr   r1, =msg          @ ponteiro para a string
    ldr   r2, =msg_len      @ número de bytes
    mov   r7, #4            @ syscall 4 = write
    svc   #0

    @ exit(42)  -- código de saída visível no shell
    mov   r0, #42
    mov   r7, #1            @ syscall 1 = exit
    svc   #0

.data
msg:
    .ascii "hello from a real ELF\n"
msg_len = . - msg          @ tamanho calculado em link-time

Decodificando o que escrevemos:

  • .syntax unified habilita a sintaxe moderna que aceita tanto ARM quanto Thumb-2 — boa prática para todo o curso.
  • mov r0, #1 e os ldr posicionam os argumentos da write (fd, buffer, tamanho).
  • mov r7, #4 + svc #0 dispara a syscall. Repare que não hábx lr: depois de exit o processo termina.

Montando e ligando

Geramos um ELF executável estático (sem dependências de biblioteca). O ponto de entrada é o símbolo _start, que o linker coloca no e_entry do ELF — é de lá que o arm-box começa a executar.

arm-none-eabi-as -march=armv5te hello.s -o hello.o
arm-none-eabi-ld -static -o hello.elf hello.o

Quer conferir o binário antes de rodar? arm-none-eabi-objdump -d hello.elf mostra a desmontagem — ótimo exercício para o próximo módulo do curso, onde decodificamos essas instruções "à mão".

Rodando no arm-box

Com o arm-box já buildado:

java -jar target/armbox-1.0-SNAPSHOT.jar hello.elf

Saída esperada:

hello from a real ELF

O código de saída do processo é o exit() do guest — no nosso caso, 42. Você pode confirmar com echo $? (ou echo %ERRORLEVEL% no Windows).

Inspecionando a execução

O arm-box herda os backends do arm-jitter. Dois flags são ouro para aprender:

  • --interp: roda no interpretador IR (referência de semântica), ótimo para entender passo a passo.
  • --check: executa JIT e interpretador em paralelo e aborta na primeira divergência — prova que os dois motores concordam.
java -jar target/armbox-1.0-SNAPSHOT.jar --check hello.elf

Próximos passos

Parabéns — você acabou de fazer um binário ARM real executar dentro de um emulador escrito em Java. A partir daqui vamos descer camadas: no próximo texto veremos o banco de registradores e o CPSR, depois como ler o objdump e decodificar instruções ARM à mão, e então abrir o capô do arm-jitter para entender o ArmCore e o decodificador. Se quiser acompanhar o curso do início, confira a lista de artigos. Até a próxima!