2 Punkte von GN⁺ 2026-02-08 | Noch keine Kommentare. | Auf WhatsApp teilen
  • SectorC, geschrieben in x86-16-Assembly, ist ein extrem kleiner C-Compiler, der in den Bootsektor (512 Byte) einer x86-Maschine passt und eine Teilmenge der C-Sprache unterstützt, die groß genug ist, um tatsächlich lauffähige Programme zu schreiben
  • Unterstützt werden unter anderem globale Variablen, Funktionen, if/while-Anweisungen, Operatoren, Pointer-Dereferenzierung, Kommentare und Inline-Assembly, sodass selbst mit minimaler Struktur vollständige Programme ausgeführt werden können
  • Um den Tokenizer zu vereinfachen, wurde mit leerzeichenbasierter Tokenisierung und einem atoi()-Hash die Sprache Barely C entworfen, die die bestehende C-Syntax beibehält und zugleich eine extreme Größenreduktion erreicht
  • Bei der Code-Optimierung wurden verschiedene Komprimierungstechniken auf Assembly-Ebene eingesetzt, darunter Entfernung von Sprüngen, Zusammenlegung von Aufrufen, Nutzung von 8-Bit-Offsets sowie stosw/lodsw, wodurch der Code von 468 Byte auf 303 Byte schrumpfte
  • Im Ergebnis wurde innerhalb von 512 Byte ein vollständiger C-Compiler inklusive Tokenizer, Parser, Codegenerator und Runtime implementiert und damit ein extremes Beispiel für Software-Minimierung gezeigt

Überblick über SectorC

  • SectorC ist ein in x86-16-Assembly geschriebener C-Compiler, der vollständig in einen 512-Byte-Bootsektor passt
    • Das GitHub-Repository ist xorvoid/sectorc
    • Die unterstützte Sprache ist eine C-Teilmenge, mit der sich reale Programme schreiben lassen
  • Zu den unterstützten Funktionen gehören globale Variablen, Funktionen, Kontrollstrukturen (if/while), verschiedene Operatoren, Pointer-Dereferenzierung, Inline-Assembly und Kommentare
  • Als Beispielprogramm wird Code zum Zeichnen einer Sinuswellen-Animation im VGA-Modus gezeigt

Designhintergrund und Ansatz

  • Da ein herkömmlicher C-Tokenizer so groß ist, dass er in 512 Byte praktisch unmöglich unterzubringen wäre, musste die Sprachstruktur selbst vereinfacht werden
  • Big Insight #1: Wie bei der Sprache Forth wurde eine durch Leerzeichen getrennte Token-Struktur eingeführt und eine abgewandelte Sprache namens „Barely C“ entworfen
    • Beispiel: Syntax wie int(main)(){while(!done){ wird als einzelnes „Mega-Token“ behandelt
    • Sie wird auch von bestehenden C-Compilern weiterhin als gültiger C-Code erkannt
  • Big Insight #2: Die Funktion atoi() wird wie eine Hash-Funktion verwendet, um Tokens in Zahlen umzuwandeln
    • Integer-Literale, Schlüsselwörter und Bezeichner werden alle über den Rückgabewert von atoi() verarbeitet
    • Auf Bezeichner wird über ihren Index in einem 64K-Array zugegriffen

Umsetzung von Barely C

  • Die erste Implementierung war 468 Byte groß und nutzte einen rekursiven Abstiegparser mit atoi-basierten Tokens
    • Ohne Symboltabelle wird direkt über den Hashwert auf ein 64K-Segment zugegriffen
    • Die Codegenerierung folgt dem OTCC-Stil und verwendet das Register ax als Speicherort für Ergebnisse
  • Später wurde mit byte-threaded code experimentiert, um eine Forth-artige Struktur zu versuchen, doch innerhalb von 512 Byte erwies sich das als eher ineffizient und wurde verworfen

Techniken zur Code-Minimierung

  • Durch die Rückkehr zu einer geradlinigen Struktur schrumpfte der Code von 468 Byte auf 303 Byte
    • Verwendet wurden Techniken wie Fall-through zur Sprungvermeidung, Tail-Call, Call Fusion, Nutzung von stosw/lodsw und das Beibehalten von 8-Bit-Sprung-Offsets
  • Dadurch wurden 207 Byte freier Platz für zusätzliche Funktionen gewonnen

Ausbau zu vollständigerer C-Funktionalität

  • Mit zusätzlichen 200 Byte wurde Unterstützung für vollständige C-Syntax erreicht
    • Verschachtelte if-/while-Blöcke sowie verschiedene *binäre Operatoren (+, -, , &, |, ^, <<, >>, ==, !=, <, >, <=, >=)
    • Unterstützung für Funktionsdefinitionen und rekursive Aufrufe, Inline-Assembly (asm) sowie einzeilige und mehrzeilige Kommentare
    • Über eine Operatortabelle (binary_oper_tbl) wird jeder Operator mit 4 Byte definiert, sodass 14 Operatoren in 56 Byte verarbeitet werden

Grammatikstruktur

  • Die gesamte Grammatik besteht aus program, var_decl, func_decl, statement, expr usw.
  • Sowohl //- als auch /* */-Kommentare werden unterstützt
  • Der Text der Grammatikdefinition selbst ist mit 704 Byte größer als die eigentliche Implementierung

Inline-Assembly und Runtime

  • Über die asm-Syntax kann x86-16-Maschinencode direkt eingefügt werden
    • Eine unverzichtbare Funktion für I/O-Verarbeitung
  • Die Runtime (rt/) besteht aus zwei in C geschriebenen Dateien
    • rt/lib.c: Bibliotheksroutinen auf Basis von Inline-Assembly
    • rt/_start.c: Programmeinstiegspunkt _start()

Beispielprogramme

  • examples/hello.c: Gibt Text direkt in den Speicher 0xB8000 aus
  • examples/sinwave.c: Zeigt eine Sinuswellen-Animation im VGA-Modus 0x13 an
  • examples/twinkle.c: Spielt „Twinkle Twinkle Little Star“ über den PC-Lautsprecher ab (mit Lautstärkewarnung)

Fazit

  • SectorC ist ein ultrakleiner C-Compiler, der ein scheinbar unmögliches Ziel erreicht, und zeigt ein extremes Beispiel für Software-Minimierung und kreatives Sprachdesign
  • Der Artikel endet mit humorvollen Auswahlmöglichkeiten zu „Was haben wir gelernt?“ und betont satirisch die Haltung, das Unmögliche herauszufordern, sowie den Wert der Vereinfachung von Software

Noch keine Kommentare.

Noch keine Kommentare.