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:
xcode-select --install
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_startzum 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:
adrplädt die Seiten-Adresse (4KB Page)addaddiert 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.