Atualizado: 30/08/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Primeiro Programa Assembly no macOS com NASM

Escrever Assembly no macOS em processadores Intel (arquitetura x86-64) é uma experiência única, com suas próprias convenções e ferramentas. Este guia irá conduzi-lo através da configuração do ambiente, da criação de um programa funcional e das particularidades da plataforma.

Montando seu Kit de Ferramentas

Para criar um executável a partir do código Assembly, precisamos de duas ferramentas essenciais: um montador e um linker.

1. O Montador: Instalando o NASM

A maneira mais simples e recomendada de instalar o NASM no macOS é usando o gerenciador de pacotes Homebrew. Se você ainda não o tem, instale-o com este comando no Terminal:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Com o Homebrew pronto, instalar o NASM é um único comando:

brew install nasm

2. O Linker: Xcode Command Line Tools

O linker padrão no macOS é o ld, que faz parte do conjunto de ferramentas do compilador Clang. A forma mais fácil de obtê-lo é instalando o Xcode Command Line Tools.

Para verificar se as ferramentas já estão instaladas, digite clang -v no Terminal. Se você vir a versão do Clang, está tudo pronto. Se receber um erro, instale as ferramentas explicitamente com:

xcode-select --install

O Primeiro Programa

Vamos começar com um programa que apenas encerra sua execução. Crie um arquivo chamado hello.asm com o seguinte conteúdo:

global _start           ; Torna o rótulo _start visível externamente

section .text           ; Declaração da seção de código
align 4                 ; Alinhamento necessário para o macOS
_start:                 ; Ponto de entrada do programa
    mov rax, 0x02000001 ; Syscall para exit
    mov rdi, 22         ; Código de retorno arbitrário: 22
    syscall             ; Executa a chamada de sistema

Analisando as Particularidades do macOS:

  • align 4: O macOS exige que o código executável seja alinhado em um limite de 4 bytes por convenção.
  • Numeração das Syscalls: Este é um ponto crucial. Pense nas chamadas de sistema do macOS como um número de telefone com código de área e ramal. O "código de área" para syscalls do kernel é 0x2000000. O "ramal" para a função exit é 1. O valor final que colocamos em rax é a soma: 0x2000000 + 1.

Do Código ao Executável: Montagem e Ligação

1. Montagem com o NASM

No Terminal, navegue até a pasta do seu projeto e execute:

nasm -f macho64 hello.asm -o hello.o

A opção -f macho64 é fundamental. Ela gera um arquivo objeto no formato Mach-O, o padrão nativo do macOS.

2. Ligação com o ld

O comando de ligação no macOS parece complexo, mas cada parte tem um propósito claro:

ld -o hello hello.o -l System -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start

Vamos decompor este comando:

  • -o hello hello.o: Cria um executável chamado hello a partir do arquivo hello.o.
  • -l System: Liga nosso programa à biblioteca de sistema principal do macOS. É como conectar nosso código à "energia" do sistema operacional.
  • -syslibroot: Informa ao linker onde encontrar as bibliotecas do sistema. O comando dentro das crases xcrun... encontra automaticamente o caminho correto.
  • -e _start: Define _start como o ponto de entrada do nosso programa.

Para executar e verificar o código de saída:

programicio@MacBook-Pro nasm % ./hello
programicio@MacBook-Pro nasm % echo $?
22

Segundo Programa: Escrevendo no Console

Agora, vamos exibir uma mensagem. Altere seu hello.asm:

global _start

section .text
align 4
_start:
    mov rax, 0x02000004     ; Syscall para write (base + 4)
    mov rdi, 1              ; Descritor de arquivo: 1 para stdout
    lea rsi, [rel message]  ; Endereço da mensagem (relativo a RIP)
    mov rdx, 19             ; Tamanho da mensagem em bytes
    syscall                 ; Executa a chamada de sistema

    mov rax, 0x02000001     ; Syscall para exit (base + 1)
    syscall                 ; Executa a chamada de sistema

section .data
message: db "Hello Programicio!", 10  ; Nossa string e uma quebra de linha

Analisando a Maior Diferença: Endereçamento Relativo

  • A syscall para write no macOS é a de número 4, então rax recebe 0x2000004.
  • A linha lea rsi, [rel message] é a mudança mais importante. Por segurança, os sistemas operacionais modernos (incluindo o macOS) carregam programas em locais aleatórios na memória. Isso é chamado de Código Independente de Posição (PIE).

    • O Problema: Não podemos usar um endereço de memória fixo para nossa message.
    • A Solução: Usamos o endereçamento relativo. lea rsi, [rel message] significa: "Carregue em rsi o endereço da message, calculado a partir da minha posição atual (o registrador rip)". É como dar direções ("três casas à frente") em vez de um endereço absoluto ("Rua Principal, 123").

O tamanho da mensagem é de 19 bytes (18 para "Hello Programicio!" + 1 para a quebra de linha).

O processo de montagem e ligação é exatamente o mesmo. O resultado será:

programicio@MacBook-Pro nasm % ./hello
Hello Programicio!

Resumo

  • Instalação: Use Homebrew para instalar o NASM e o Xcode Command Line Tools para obter o linker (ld).
  • Formato de Arquivo: O formato de saída para o macOS é macho64.
  • Chamadas de Sistema: As syscalls do kernel têm uma base de 0x2000000, à qual o número da função é somado (exit = 1, write = 4).
  • Ligação: A ligação com ld no macOS requer parâmetros específicos para vincular à biblioteca do sistema (-l System) e definir o ponto de entrada (-e _start).
  • Endereçamento Relativo: O código no macOS é independente de posição, o que torna obrigatório o uso de endereçamento relativo ao rip (lea [rel ...]) para acessar dados.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com