16바이트 데모의 예술: 'Wake Up!' 해체하기
데모씬(demoscene)의 세계에는 "sizecoding"이라 불리는 분야가 있습니다. 이는 복잡한 시각적 및 청각적 경험을 가능한 가장 작은 바이너리 크기로 압축하는 기술입니다. 현대 소프트웨어는 기가바이트 단위로 측정되지만, sizecoding의 가장 극단적인 사례들은 바이트 단위로 작동합니다.
최근 HellMood가 제작한 "Wake up! 16b"라는 프로젝트가 기술 커뮤니티의 주목을 받고 있습니다. 단 16바이트의 x86 real-mode DOS 어셈블리로, 이 프로그램은 화면에 무한한 Sierpinski 프랙탈을 생성하는 동시에 PC 스피커를 통해 동기화된 거친 사운드스케이프를 출력합니다. 이것은 단순한 압축 기술이 아니라, 알고리즘 밀도와 하드웨어 활용의 정수입니다.
16바이트 소스 코드
이 마법을 이해하려면 먼저 코드를 살펴보아야 합니다. 전체 프로그램은 다음과 같은 명령어로 구성됩니다:
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
캔버스: 준비된 공허(Primed Void)의 활용
프로그램은 int 10h로 시작하며, 이는 비디오 모드를 40x25 텍스트 그리드로 설정합니다. 그 다음 데이터 세그먼트(ds)를 VGA/CGA 텍스트 버퍼의 메모리 주소인 0xb800으로 지정합니다.
여기서 중요한 세부 사항은 BIOS가 화면을 절대적인 0으로 지우지 않는다는 점입니다. 대신, 메모리를 균일한 패턴으로 채웁니다: 0x20 (ASCII 공백 문자) 및 0x07 (검은색 배경의 밝은 회색). 이는 메모리가 빈 도화지가 아니라, 프로그램의 계산을 위한 초기 데이터를 제공하는 "준비된 공허"임을 의미합니다.
엔진: 가산 접두사 합(Additive Prefix Sums)과 이항 계수
이 프로그램의 핵심은 셀룰러 오토마타(cellular automaton)로 작동한다는 점입니다. 비디오 메모리를 계산 공간으로 취급함으로써, 시간이 지남에 따라 진화하는 일련의 연산을 수행합니다.
로직을 단순화하여—0으로 초기화된 상태를 가정하고 xor 대신 add를 사용한다고 가정하면—프로그램은 본질적으로 부분 합을 생성합니다. DOS 세그먼트는 65,536바이트이며 루프가 순환하므로, 값들은 이항 계수 수열을 따릅니다. 프로그램이 메모리를 훑으며 지나갈 때, 각 순환의 시작 부분에서 깔끔하게 리셋되면서 8비트 레지스터 크기에 완벽하게 일치하는 값들을 축적합니다.
결정화: XOR과 Sierpinski 삼각형
단순한 덧셈에서 시각적 프랙탈로의 전환은 xor 명령어를 통해 일어납니다. 조합론에서 2를 법으로 하는 덧셈(addition modulo two)을 수행할 때 Sierpinski 삼각형이 나타납니다.
add 대신 xor를 사용함으로써, 프로그램은 특정 비트 평면(bitplanes)을 분리합니다. 초기 상태(및 그 이후의 연산)가 특정 비트를 대상으로 하기 때문에, 이는 기본 셀룰러 오토마타의 Rule 60을 효과적으로 구현합니다. 루카스 정리(Lucas's theorem)는 이 과정이 Sierpinski 프랙탈의 특징인 자기 유사성 패턴을 생성할 것을 보장합니다.
기계의 목소리: 바이트비트(Bytebeats)
"Wake up!"의 가장 놀라운 요소는 오디오입니다. 이는 out 61h, al 명령어를 통해 구현됩니다.
포트 61h는 PC 스피커와 직접 연결됩니다. 이 포트로 전송되는 바이트의 1번 비트는 스피커 콘(cone)을 제어어(1은 출력, 0은 입력)합니다. 프로그램이 프랙탈을 계산하고 있기 때문에, 결과로 나오는 1과 0의 스트림은 펄스 폭과 주파수가 변하는 사각파를 사각파를 생성합니다.
흥미롭게도, 이 소리는 "순수한" 수학적 톤이 아닙니다. 프로그램이 섀도우 비디오 ROM BIOS 코드를 포함한 전체 64KB 세그먼트를 반복하며 지나가기 때문에, 오디오에는 시스템 자체의 펌웨어의 "노이즈"가 포함되어 거친 텍스트처를 만들어냅니다.
56바이트 스텝: 시각적 전단(Shearing)
"Matrix rain" 효과를 만들기 위해 저자는 특정 스텝 사이즈를 사용합니다. lodsb (which increments si)와 sub si, byte 57의 조합은 반복당 -56바이트의 순수 이동량을 결과로 가져옵니다.
이 선택은 두 가지 심오한 효과를를 가져옵니다:
- 오디오 옥타브 이동: 56은 65,536을 나누어 떨어뜨리지 않습니다. 루프는 순환하기 위해 8,192단계를 거치며, 이는 사이클 길이를 두 배로 늘리고 소리의 기본 주파수를 한 옥타브 낮춥니다.
- 시각적 전단(Visual Shearing): 80열 화면에서 56바이트 뒤로 이동하는 것은 24바이트(12열) 앞으로 이동하는 것과 같습니다. 이로 인해 프랙탈이 대각선으로 전단되어, 정적인 삼각형이 아닌 위로 움직이는 10개의 문자 기둥이 나타납니다.
Sizecoding의 철학학
"Wake up! 16b"는 저수준 프로그래밍의 근본적인 진리를 보여줍니다: 하드웨어는 단순한 대상이 아니라 협력자입니다. BIOS의 "아티팩트"와 IBM PC의 특정 메모리 레이아웃을 활용함으로써, 저자는 거의 아무것도 없는 상태에서 복잡성을 창성성합니다.
커뮤니티의 언급처럼, 이 정도의 밀도는 종종 "검은 마법"이라 느껴집니다. 한 관찰자는 다음과 같이 말했습니다:
"I really thought that a 32 byte demo I sizecd was the limit of the limit of how small the binary can get and still look good... This is hell of a good work. A masterpiece. "
거대한 LLM과 비대해해진 프레임워크의 시대에, 이와 같은 프로젝트는 컴퓨팅의 가공되지 않은 아름다움을 상기시켜 줍니다. 정교하게 설계된 몇 바이트의 어셈블리가 복잡한 수학적 우주를 불러일으킬 수 있다는 것을 말이죠.