2 points par GN⁺ 2026-02-08 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • SectorC, écrit en assembleur x86-16, est un compilateur C ultracompact qui tient dans le secteur d’amorçage (512 octets) d’une machine x86, et il prend en charge un sous-ensemble du langage C suffisant pour écrire de vrais programmes exécutables
  • Il inclut notamment les variables globales, fonctions, instructions if/while, opérateurs, déréférencement de pointeurs, commentaires et assembleur inline, ce qui permet d’exécuter des programmes complets avec une structure minimale
  • Pour simplifier le tokenizer, il introduit un langage Barely C fondé sur une tokenisation par espaces et un hachage via atoi(), tout en conservant la syntaxe C existante pour obtenir une réduction de taille extrême
  • Au cours de l’optimisation, diverses techniques de compression au niveau assembleur ont été appliquées, comme la suppression de sauts, la fusion d’appels, l’usage d’offsets sur 8 bits et de stosw/lodsw, ce qui a permis de passer de 468 octets à 303 octets
  • Au final, le projet parvient à implémenter dans 512 octets un compilateur C complet incluant tokenizer, parseur, générateur de code et runtime, illustrant un cas extrême de minimisation logicielle

Présentation de SectorC

  • SectorC est un compilateur C écrit en assembleur x86-16 qui tient entièrement dans un secteur d’amorçage de 512 octets
    • Le dépôt GitHub est xorvoid/sectorc
    • Le langage pris en charge est un sous-ensemble de C suffisant pour écrire de vrais programmes
  • Les fonctionnalités prises en charge comprennent les variables globales, fonctions, structures de contrôle (if/while), divers opérateurs, déréférencement de pointeurs, assembleur inline et commentaires
  • Un programme d’exemple montre du code qui dessine une animation sinusoïdale en mode VGA

Contexte de conception et approche

  • Un tokenizer C classique étant bien trop volumineux pour tenir dans 512 octets, il a fallu simplifier la structure même du langage
  • Big Insight #1 : à la manière de Forth, le projet adopte une structure de tokens séparés par des espaces et conçoit une variante appelée « Barely C »
    • Exemple : int(main)(){while(!done){ est traité comme un unique « méga-token »
    • Cela reste reconnu comme du code C valide par les compilateurs C existants
  • Big Insight #2 : la fonction atoi() est utilisée comme fonction de hachage pour convertir les tokens en nombres
    • Les littéraux entiers, mots-clés et identifiants sont tous traités à partir du résultat de atoi()
    • Les identifiants sont accessibles comme index dans un tableau de 64K

Implémentation de Barely C

  • La première implémentation faisait 468 octets et reposait sur un parseur récursif descendant utilisant des tokens basés sur atoi
    • Sans table des symboles, elle accédait directement au segment 64K via la valeur de hachage
    • La génération de code suivait un style OTCC en utilisant le registre ax comme emplacement de résultat
  • Ensuite, une expérimentation avec du byte-threaded code a tenté une structure à la Forth, mais elle s’est révélée au contraire inefficace dans la limite des 512 octets et a donc été abandonnée

Techniques de minimisation du code

  • Le projet est revenu à une structure linéaire et a réduit la taille de 468 octets à 303 octets
    • Utilisation de techniques comme le fall-through (suppression de sauts), le tail-call, la fusion d’appels, l’usage de stosw/lodsw et le maintien de déplacements de saut sur 8 bits
  • Cela a libéré 207 octets d’espace pour ajouter des fonctionnalités

Extension vers des fonctionnalités C complètes

  • Avec 200 octets supplémentaires, le projet a atteint une prise en charge complète de la syntaxe C visée
    • Blocs if/while imbriqués, divers opérateurs binaires (+, -, *, &, |, ^, <<, >>, ==, !=, <, >, <=, >=)
    • Prise en charge des définitions de fonctions et appels récursifs, de l’assembleur inline (asm), ainsi que des commentaires sur une ligne et multilignes
    • Une table des opérateurs (binary_oper_tbl) permet de définir chaque opérateur en 4 octets, soit 14 opérateurs pour 56 octets

Structure grammaticale

  • La grammaire complète se compose notamment de program, var_decl, func_decl, statement, expr, etc.
  • Les commentaires // et /* */ sont tous deux pris en charge
  • Le texte décrivant la grammaire occupe à lui seul 704 octets, soit plus que l’implémentation elle-même

Assembleur inline et runtime

  • L’instruction asm permet d’insérer directement du code machine x86-16
    • C’est une capacité indispensable pour les entrées/sorties
  • Le runtime (rt/) se compose de deux fichiers écrits en C
    • rt/lib.c : routines de bibliothèque fondées sur l’assembleur inline
    • rt/_start.c : point d’entrée du programme _start()

Programmes d’exemple

  • examples/hello.c : affiche du texte directement dans la mémoire 0xB8000
  • examples/sinwave.c : affiche une animation sinusoïdale en mode VGA 0x13
  • examples/twinkle.c : joue « Twinkle Twinkle Little Star » sur le haut-parleur PC (avec avertissement sonore)

Conclusion

  • SectorC est un compilateur C minuscule qui concrétise un objectif apparemment impossible, et montre un cas extrême de minimisation logicielle et de conception créative de langage
  • La fin de l’article se conclut sur des choix humoristiques autour de « ce que l’on a appris », soulignant avec ironie l’intérêt de s’attaquer à l’impossible et la valeur de la simplification logicielle

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.