Débuter en Assembleur ARM64 natif sous macOS Tahoe

Introduction

Ce guide vous explique comment écrire, assembler et exécuter votre premier programme en langage assembleur ARM64 natif sur un Mac Apple Silicon sous macOS Tahoe. Pas de machine virtuelle, pas d'émulation : le code s'exécute directement sur le processeur de votre Mac.

L'assembleur est le langage le plus proche du processeur. Chaque instruction que vous écrivez correspond à une opération élémentaire que le CPU exécute directement. C'est la façon la plus directe de comprendre ce que fait réellement votre machine.

Sur Apple Silicon (puce M1, M2, M3, M4…), l'architecture est ARM64 (AArch64). Les outils nécessaires (as et clang) sont fournis gratuitement par Apple via les Xcode Command Line Tools, installés automatiquement avec Homebrew.


Concepts de base à connaître

Avant de commencer, voici quelques notions indispensables pour comprendre le code que vous allez écrire :


Étape 1 — Vérifier les outils de base

Xcode Command Line Tools

Les outils as (assembleur) et clang (compilateur/lieur) font partie des Xcode Command Line Tools. Si Homebrew est déjà installé, ils sont déjà présents. Vérifiez-le avec :

xcode-select --version

La réponse attendue ressemble à : xcode-select version 2416.

Vérifier as et clang

Confirmez ensuite que l'assembleur et le compilateur sont bien disponibles, et qu'ils ciblent bien arm64-apple-darwin :

as --version && clang --version

(La mention Target: arm64-apple-darwin confirme que vous travaillez bien en natif ARM64, sans émulation Rosetta.)


Étape 2 — Consulter la liste des syscalls

Les numéros de syscalls macOS sont définis dans un header du SDK Apple, directement sur votre machine. C'est la référence officielle pour connaître le numéro à placer dans x16 :

cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h

Les syscalls les plus utiles pour débuter :

(Ce fichier est généré automatiquement depuis le source du noyau XNU d'Apple. La liste complète contient 558 entrées à ce jour.)


Étape 3 — Créer un répertoire de travail

Créez un dossier dédié à vos expérimentations en assembleur et placez-vous dedans :

mkdir ~/asm-test && cd ~/asm-test

Étape 4 — Écrire le programme

Créer le fichier source

Créez le fichier hello.s (l'extension .s est la convention standard pour les fichiers source en assembleur) :

cat > hello.s << 'EOF'
.global _main
.align 2

_main:
 ; write(1, msg, 14)
 mov x0, #1 ; fd = stdout
 adr x1, msg ; pointeur vers le message
 mov x2, #14 ; longueur (13 caractères + \n)
 mov x16, #4 ; syscall write
 svc #0x80

 ; exit(0)
 mov x0, #0 ; code de retour
 mov x16, #1 ; syscall exit
 svc #0x80

msg:
 .ascii "Hello, World!\n"
EOF

Comprendre le code ligne par ligne

Convention d'appel ARM64 macOS (résumé)

Pour un syscall sur macOS ARM64, la convention est toujours la même :


Étape 5 — Assembler et lier

On utilise clang qui appelle l'assembleur as puis le lieur en une seule commande :

clang -o hello hello.s && echo "OK"

Si la réponse est OK, le fichier exécutable hello a été créé. En cas d'erreur, le message indiquera la ligne fautive dans votre fichier .s.

(Pourquoi clang et pas directement as ? Clang gère automatiquement l'édition de liens, la signature de code macOS et les options de compilation. C'est la méthode recommandée pour les exécutables macOS.)


Étape 6 — Exécuter le programme

./hello

Résultat attendu :

Hello, World!

(Si vous observez un % collé en fin de ligne sans retour à la ligne, c'est que le compteur d'octets dans x2 est inférieur à la longueur réelle de la chaîne. Vérifiez que x2 = 14 pour inclure le \n.)


Récapitulatif des commandes

Voici l'ensemble du flux de travail en une seule séquence :

# Vérifier les outils
xcode-select --version
as --version && clang --version

# Consulter la liste des syscalls
cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h

# Créer un répertoire de travail
mkdir ~/asm-test && cd ~/asm-test

# Écrire le programme
cat > hello.s << 'EOF'
.global _main
.align 2

_main:
 mov x0, #1
 adr x1, msg
 mov x2, #14
 mov x16, #4
 svc #0x80

 mov x0, #0
 mov x16, #1
 svc #0x80

msg:
 .ascii "Hello, World!\n"
EOF

# Assembler et lier
clang -o hello hello.s && echo "OK"

# Exécuter
./hello

Conclusion

Vous avez écrit, assemblé et exécuté votre premier programme en assembleur ARM64 natif sur macOS, sans aucun outil tiers, uniquement avec ce qu'Apple fournit. Le programme dialogue directement avec le noyau macOS via deux syscalls : write pour afficher du texte, et exit pour terminer proprement.

La prochaine étape naturelle est d'explorer des syscalls supplémentaires (lecture au clavier avec read, gestion de fichiers avec open/close), d'apprendre à créer des boucles et des conditions en ARM64, ou d'utiliser otool -tv hello pour désassembler votre binaire et observer le code machine généré.



↑ Haut de page