16バイトの芸術:x86 Assemblyにおけるシェルピンスキーのフラクタルの設計
ソフトウェアにおける極限のミニマリズムの追求は、しばしば好奇心の対象と見なされますが、デモシーン(demoscene)においては、それは厳格な規律です。2026年5月のOutline DemopartyでHellMoodによってリリースされたデモ「"Wake up! 16b"」は、この規律の頂点を象徴しています。これは、わずか16バイトのx86 real-mode DOS assemblyのみを使用して、同期されたオーディオとビジュアルの両方を生成する完全に機能的なプログラムです。
これは単なる「ハック」ではなく、アルゴリズムの密度の洗練された応用であり、ハードウェア固有の状態を利用して、二項係数の性質を用いてシェルピンスキーの三角形フラクタルを作成します。ここでは、これら16バイトがどのように1980年代のPCを操作して、複雑な創発的挙動を生み出すのかを深く掘り下げていきます。
コード
その魔法を理解するためには、まずソースを見る必要があります。プログラム全体は以下の命令で構成されています。
int 10h ; 2 bytes
mov bh, 0xb8 ; 2 bytes
mov ds, bx ; 2 bytes
L:
lodsb ; 1 byte
sub si, byte 57 ; 3 bytes
xor [si], al ; 2 bytes
out 61h, al ; 2 bytes
jmp short L ; 2 bytes
1. キャンバスの準備
プログラムは、ビデオモードを40x25のテキストグリッドにリセットするBIOS割り込み int 10h を呼び出すことから始まります。極めて重要なのは、これが単に画面を消去するだけでなく、ビデオメモリを 0xb800 で特定のパターンで初期化することです。各文字スロットは2バイトで構成されています。ASCII文字(スペースのために 0x20 で初期化)と、カラー属性(黒背景に明るいグレーの 0x07 で初期化)です。
メモリを明示的にゼロクリアするのではなく、この既存の状態に依存することで、作者は貴重なバイト数を節約しています。その後、プログラムはデータセグメント (ds) を 0xb800 に向け、VGA/CGAテキストバッファを計算用のワークスペースへと実質的に変えます。
2. エンジン:加法的累積和
その核心において、このデモはセル・オートマトンとして機能します。数学を理解するために、メモリがゼロクリアされており、プログラムが一度に16バイトずつ進む簡略化されたバージョンを想像してください。
プログラムが反復するにつれ、メモリセグメント全体にわたって加算を行います。DOSセグメントは正確に65,536バイトであるため、固定の増分で移動することで、ポインタが綺麗にラップアラウンド(一周)することを保証します。このプロセスは、二項数列に従う部分和を作成します。これらの値がスケールされ、反復されると、、8ビットレジスタのサイズと完璧に一致するキャリー(桁上げ)とオーバーフローのパターンを形成します。
3. XORによる結晶化
加算が二項数列を作成する一方で、作者は特定のビットプレーンを分離するために xor を使用します。バイナリ論理において、XORは本質的にキャリー(桁上げ)のない加算です。
システムの初期状態(および操作される特定の値)がビット1(バイナリ 00000010)をターゲットにしているため、プログラムは初等セル・オートマトンの Rule 60 を効果的に実装しています。ルーカス(Lucas's)の定理によれば、この特定の剰余2の演算が、二項係数からシェルピンスキーの三角形を出現させる原因です。XOR演算は、この特定のビットの反転(toggling)のみが記録され、再生されることを保証します。
4. 共感覚:データからオーディオへ
このデモの最も際立った特徴の一つは、音と視覚の同期です。これは out 61h, al という命令によって達成されます。
ポート 61h はPCスピーカーのインターフェースです。このポートに送られるバイトのビット1は、スピーカーコーンを制御します(1は出力、0は入力)。XOR計算の結果をスピーカーポートに直接送り込むことで、フラクタルの幾何学が矩形波へと変換されます。
フラクタルが進化するにつれ、これらの波のパルス幅と周波数が変化し、自己相似的な「バイトビート(bytebeats)」を生み出します。興味深いことに、音は、プログラムがシャドウ・BIOS ROMコードを含む64KBセグメント全体を反復することによってさらに豊かになり、クリーンな環境では存在しない「ザラついた」テクスチャをオーディオに加えます。
5. 空間的歪み:56バイトのステップ
視覚的な「マトリックス・レイン」効果を作成するために、作者は単純な線形進行を避けています。前に進む代わりに、コードは sub si, byte 57 と lodsb(si を1増やす)を組み合わせ、結果として1回の反復につき -56バイト の純粋な移動量となります。
この選択には、2つの深い効果があります。
- オーディオのオクターブ・シフト: 56は65,536を割り切れません。プログラムはセグメントを一周するために8,192ステップを要し、サイクル長を倍増させ、音の基本周波数を1オクターブ下げます。
- 視覚的シアリング(ずれ): 80列の画面において、56バイト戻ることは24バイト(12列)進むことと等価です。これにより、フラクタルが斜めにシアリング(ずれ)を起こし、静止した三角形ではなく、10本の文字の柱が上に向かって移動しているように見えます。
ハードウェアへの感度
プログラムはRAMの既存の内容に対してXORを行うため、出力は環境に非常に敏感です。異なるBIOSバージョンやエミュレータはメモリ内に異なるアーティファクト(痕跡)を残すため、これは、実行されるマシンに応じてデモの音と見た目がわずかに異なることを意味します。
コミュニティのメンバーであり、scener miragept が指摘したように、MDAモニター付きのIBM 286のような実機ハードウェアでコードを実行することは、旧式モニターのリン光(phosphor)の残像効果により、シェルピンスキーの三角形の構造をより鮮明に見せることができます。ハードウェアの自然な状態を受け入れることは、サイズコーディング(sizecoding)の真髄であり、そこでは環境はバグではなく、機能です。
"ハードウェアの自然な状態を受け入れることは、サイズコーディングの魅力の一部に過ぎません。"
この16バイトの傑作は、複雑さが量(ボリューム)を必要としないことを証明しています。数学、ハードウェア・アーキテクチャ、およびアセンブリ言語の深い交差点を理解することで、数バイトのコードがフラクタルの創発的な美しさを呼び起こすことができます。