SBCL 内联汇编实战:环形寄存器栈的 VM 实现

SBCL 内联汇编实战:环形寄存器栈的 VM 实现

_

Paul Khuong 在 2014 年的一篇博客中演示了如何借助 SBCL 的内联汇编器,将 x86-64 通用寄存器 r8–r15 当作一个 环形栈 来使用,实现「零数据搬运」的 push/pop 操作。

灵感来源

这一思路受 Chuck Moore F18 仅有 10 个栈槽的设计和 djb 关于 x87 旋转栈可与寄存器等效的观点启发。核心洞察是:若栈容量固定且较小(如 8 个槽),可以在编译期为每个栈指针值生成专门的原语代码,从而避免运行时的数据搬移。

环形栈实现

Paul 把 r8–r15(32 位)映射为栈的后备存储,用一个全局的模 8 计数器 *stack-pointer* 指向当前栈顶。访问第 i 个栈元素时,计算 (i + *stack-pointer*) mod 8 并索引寄存器数组。这意味着 push/pop 只需增减计数器,无需搬移寄存器中的数据。

代码分派优化

传统直接线程虚拟机中,原语以 add rsi, 8; jmp [rsi-8] 结尾跳转至下一条指令。Paul 改为在基地址 rdi 加上一个变体偏移量(variant_offset),使得每种栈指针状态对应独立的代码块:

mov eax, [rsi]
add rsi, 4
lea rax, [rax + rdi + variant_offset]
jmp rax

他把每个原语的 8 种变体间隔 4288 字节存储,实现「通过地址计算分派」而非条件分支。生成代码时只需遍历 *stack-pointer* 取值 0–7,调用同一套原语生成函数即可得到全部变体。

开发体验

Paul 借助 SLIME 的 REPL 和 SBCL 内置汇编器(sb-assem:inst 等)进行原型开发,边生成机器码边调试。他认为这种环境比传统的「写文件→编译→运行」循环更高效,适合探索高度重复的代码生成任务。

编注:原文写于 2014 年,介绍一种利用 SBCL 汇编器做代码生成的技术思路,代码细节丰富但未提供完整可运行示例,适合对编译器/VM 实现感兴趣的读者参考。


秒级音频生成:Stability AI 开源 Stable Audio 3,支持分钟级合成与局部编辑 2026-05-20
字节跳动开源Lance:30亿参数统一多模态模型,图文视频生成理解一体化 2026-05-20