ARM64 Assembly Tutorial – Teil 1: Setup und erste Schritte

ARM64 Assembly für Einsteiger – Teil 1: Setup und erste Schritte

Einleitung

Willkommen zu dieser Tutorial-Serie über ARM64 Assembly-Programmierung! In dieser Serie lernst du, wie moderne Apple Silicon Macs (M1, M2, M3, M4) auf unterster Ebene programmiert werden.

Was ist Assembly? Assembly ist die Programmiersprache, die am nächsten an der Hardware liegt. Jeder Befehl entspricht direkt einer CPU-Instruktion. Während höhere Sprachen wie Python oder C dir vieles abnehmen, hast du in Assembly die vollständige Kontrolle über jeden einzelnen Schritt, den der Prozessor ausführt.

Warum ARM64? ARM64 (auch AArch64 genannt) ist die 64-Bit-Architektur von ARM-Prozessoren. Sie wird nicht nur in Apple Silicon Macs verwendet, sondern auch in:

  • Raspberry Pi (ab Modell 3)
  • Modernen Smartphones
  • Servern und Cloud-Infrastruktur

Was du lernen wirst:

  • Wie die CPU wirklich funktioniert
  • Register, Speicher und Instruktionen
  • Wie Programme auf unterster Ebene ablaufen
  • Die Grundlagen für Reverse Engineering und Debugging

Voraussetzungen

Hardware:

  • Ein Mac mit Apple Silicon (M1, M2, M3 oder M4 Chip)
  • Alternativ: Ein Raspberry Pi 3 oder neuer (Code muss leicht angepasst werden)

Software:

  • macOS (egal welche Version mit Apple Silicon)
  • Xcode Command Line Tools (installieren wir gleich)
  • Ein Terminal (ist bereits installiert)

Vorkenntnisse:

  • Grundlegendes Verständnis von Computern
  • Erfahrung mit der Kommandozeile ist hilfreich, aber nicht zwingend
  • Programmierkenntnisse in einer anderen Sprache sind von Vorteil

Installation und Setup

Schritt 1: Xcode Command Line Tools installieren

Öffne das Terminal (Programme → Dienstprogramme → Terminal) und gib ein:

Es erscheint ein Fenster, das dich durch die Installation führt. Dies kann einige Minuten dauern.

Schritt 2: Installation überprüfen

Prüfe, ob der Assembler installiert ist:

as --version

Du solltest eine Ausgabe wie diese sehen:

Apple clang version 17.0.0 (clang-1700.3.19.1)
Target: arm64-apple-darwin25.1.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Wichtig ist die Zeile Target: arm64 – das bestätigt, dass du einen Apple Silicon Mac hast.

Schritt 3: Linker überprüfen

ld -v

Erwartete Ausgabe:

@(#)PROGRAM:ld PROJECT:ld-1221.4
BUILD 16:29:08 Aug 11 2025
configured to support archs: armv6 armv7 armv7s arm64 arm64e ...

Schritt 4: SDK-Pfad ermitteln

xcrun -sdk macosx --show-sdk-path

Du solltest einen Pfad wie diesen erhalten:

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk

Notiere dir diesen Pfad – du brauchst ihn beim Kompilieren!

Dein erstes Assembly-Programm

Hello World erstellen

Erstelle eine Datei namens hello.s (das .s steht für Assembly Source):

nano hello.s

Füge folgenden Code ein:

.global _start
.align 2

.text
_start:
    adrp x1, msg@PAGE
    add x1, x1, msg@PAGEOFF
    mov x0, #1
    mov x2, #laenge
    mov x16, #4
    svc #0x80

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

.data
msg:
    .ascii "Hallo Welt!\n"
msg_ende:
    .set laenge, msg_ende - msg

Speichern mit: Ctrl+O, Enter, Ctrl+X

Was bedeutet dieser Code?

Lass uns den Code Zeile für Zeile durchgehen:

  • .global _start – Macht _start zum Einstiegspunkt des Programms
  • .align 2 – Richtet Code an 4-Byte-Grenzen aus (2^2 = 4)
  • .text – Markiert den Beginn des Code-Bereichs
  • _start: – Das Label, wo das Programm beginnt

Die beiden wichtigen Zeilen für macOS:

adrp x1, msg@PAGE
add x1, x1, msg@PAGEOFF

Diese zwei Zeilen laden die Adresse unserer Nachricht ins Register x1. Auf macOS muss dies in zwei Schritten erfolgen:

  1. adrp lädt die Seiten-Adresse (4KB Page)
  2. add addiert den Offset innerhalb der Seite

Der Syscall-Block:

mov x0, #1          // File Descriptor 1 = stdout (Bildschirm)
mov x2, #laenge     // Länge der Nachricht
mov x16, #4         // Syscall-Nummer 4 = write
svc #0x80           // Syscall ausführen

Dies ruft die write()-Funktion des Betriebssystems auf, um Text auszugeben.

Programm beenden:

mov x0, #0          // Exit-Code 0 (Erfolg)
mov x16, #1         // Syscall-Nummer 1 = exit
svc #0x80           // Programm beenden

Die Daten:

.data
msg:
    .ascii "Hallo Welt!\n"
msg_ende:
    .set laenge, msg_ende - msg

Hier wird unsere Nachricht gespeichert. Die Länge wird automatisch berechnet als Differenz zwischen Start und Ende.

Kompilieren und Ausführen

Schritt 1: Assemblieren

Wandle den Assembly-Code in Maschinencode um:

as -o hello.o hello.s

Dies erstellt eine Objektdatei hello.o.

Schritt 2: Linken

Verbinde die Objektdatei mit den System-Bibliotheken:

ld -o hello hello.o -lSystem -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -e _start -arch arm64

Erklärung der Parameter:

  • -o hello – Ausgabedatei heißt „hello“
  • -lSystem – Linke mit System-Bibliothek
  • -syslibroot ... – Pfad zum macOS SDK
  • -e _start – Einstiegspunkt ist _start
  • -arch arm64 – Zielarchitektur ist ARM64

Schritt 3: Ausführen

./hello

Du solltest sehen:

Hallo Welt!

Glückwunsch! 🎉 Du hast gerade dein erstes ARM64 Assembly-Programm geschrieben und ausgeführt!

Häufige Fehler und Lösungen

Fehler: „unknown AArch64 fixup kind!“

Problem: Du hast adr x1, msg statt adrp + add verwendet.

Lösung: Auf macOS musst du immer die zweiteilige Form verwenden:

adrp x1, msg@PAGE
add x1, x1, msg@PAGEOFF

Fehler: „library not found for -lSystem“

Problem: Das SDK wurde nicht gefunden.

Lösung: Prüfe den SDK-Pfad mit xcrun -sdk macosx --show-sdk-path und verwende ihn im ld-Befehl.

Fehler: „ld: entry point (_start) undefined“

Problem: Der Einstiegspunkt wurde nicht gefunden.

Lösung: Stelle sicher, dass dein Code .global _start enthält und ein Label _start: hat.

Nützlicher Tipp: Makefile erstellen

Um nicht jedes Mal den langen Befehl eintippen zu müssen, erstelle eine Datei namens Makefile:

ASM = as
LD = ld
SDK = /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk

hello: hello.o
    $(LD) -o hello hello.o -lSystem -syslibroot $(SDK) -e _start -arch arm64

hello.o: hello.s
    $(ASM) -o hello.o hello.s

clean:
    rm -f hello.o hello

.PHONY: clean

Dann kannst du einfach eingeben:

make hello
./hello

Zum Aufräumen:

make clean

Zusammenfassung

In diesem ersten Teil hast du gelernt:

  • ✅ Was ARM64 Assembly ist und warum es relevant ist
  • ✅ Wie man die Entwicklungsumgebung auf macOS einrichtet
  • ✅ Die Struktur eines Assembly-Programms
  • ✅ Wie man auf macOS korrekt Adressen lädt (adrp + add)
  • ✅ Was Syscalls sind und wie man sie verwendet
  • ✅ Wie man kompiliert, linkt und ausführt

Nächste Schritte

Im nächsten Teil werden wir uns mit den fundamentalen Bausteinen beschäftigen:

  • Register – die winzigen Speicher in der CPU
  • Arithmetische Operationen (Addition, Subtraktion, Multiplikation)
  • Speicher lesen und schreiben
  • Arrays und Datenstrukturen

Bis dahin: Experimentiere mit dem Hello-World-Programm! Ändere die Nachricht, füge weitere write-Aufrufe hinzu, oder versuche mehrere Zeilen auszugeben.


Dies ist Teil 1 der ARM64 Assembly Tutorial-Serie. Weiter zu Teil 2 →

1 Gedanke zu „ARM64 Assembly Tutorial – Teil 1: Setup und erste Schritte“

Die Kommentare sind geschlossen.