算法密度:将16字节的x86汇编转换为音视觉艺术
在演示场景中,追求极端约束不仅是一项技术挑战,更是一种艺术形式。最近的一款名为 "wake up! 16b" 的制作展示了这一哲学的巅峰,仅使用16字节的x86实模式DOS汇编实现了复杂的音视觉体验。
通过将计算机的视频内存视为计算空间,代码生成一个无限的谢尔宾斯基分形,并同时将该几何解释为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
画布:准备虚空
该例程以 int 10h 开始,该指令初始化视频模式0(一个40x25的文本模式网格)。关键的是,BIOS不会将屏幕清零到绝对零。相反,它用一个均匀的模式填充内存:ASCII空格字符(0x20)和浅灰色属性(0x07)。
这种均匀性至关重要。在元胞自动机中,初始状态的随机噪声可能会破坏得到的模式。通过依赖BIOS的可预测初始化,作者为分形的出现创建了一个稳定的基础。
逻辑:异或与谢尔宾斯基位移
该制作的核心是一个反馈循环。lodsb 指令将内存中的一个字节读入 AL 寄存器并递增源索引 (SI)。随后,代码修改 SI 并在当前值与内存单元之间执行 xor 操作。
从数学角度看,如果代码使用 add,它将创建一个二项式前缀和。然而,通过使用 xor,作者丢弃了算术进位并隔离了位平面。这使得计算转换为映射到 Wolfram's Rule 60 的元胞自动机。根据卢卡斯定理,这种异或关系保证能够产生谢尔宾斯基三角形。结果是在 0x00 和 0x02(位1)之间切换,从而创建分形的几何结构。
将几何转换为声音
该制作最优雅的方面之一是指令 out 61h, al。端口 61h 与内部PC扬声器接口,并且该端口的位1直接控制扬声器锥体的物理运动。
由于算法隔离并切换位1来生成分形,谢尔宾斯基三角形的几何成为扬声器的一组直接指令。CPU的执行速度决定采样率,将数学结构转换为一系列方波。在分形密集的地方(交替的位)会产生高频音调,而在三角形较大的空白区域则会出现节奏性的停顿。
空间与听觉操控
代码不会线性地遍历内存。指令 sub si, byte 57 与 lodsb 的增量结合,导致每次迭代的净移动为 -56字节。这个特定的偏移量有两个用途:
1. 视觉剪切
在一个80字节宽的文本网格上,-56字节的偏移在空间上相当于向前移动24字节。由于每个字符空间占2字节,这相当于12列的偏移。得到的分形不是连续的图像,而是被对角线剪切成十个均匀间隔的垂直柱子,其中包含升序的字形。
2. 听觉八度偏移
虽然16字节的步长可以在4096次迭代内完成一次段扫描,但56字节的步长需要8192次迭代(在64KB段上绕行七次)才能返回起点。这使得宏周期长度加倍,从而将音频的基频减半,音调恰好降低一个八度。
硬件敏感性与“指纹”
由于该例程会读取并对现有内存进行异或操作,其输出对环境高度敏感。不同的VGA BIOS实现或模拟器(如DOSBox或PCem)可能在RAM中留下不同的伪影。
因此,视觉字符和声音的音色可能在不同机器之间有所不同。虽然一个设置例程可以清除内存以确保均匀性,但这会超出16字节的限制。作者接受这种不可预测性,将硬件的自然状态转化为每次执行独特的音视觉指纹。
"值得注意的是,将此混合数据字节直接发送到系统端口61h……不会干扰系统。在标准的DOS环境和现代模拟器中,将这些额外的位推送到端口实际上是无害的。"
这一最终的巧合使得视觉ASCII数据可以安全地充当音频信号,从而最大化了16字节限制的效率。