惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AWS News Blog
AWS News Blog
Schneier on Security
Schneier on Security
P
Palo Alto Networks Blog
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
S
Secure Thoughts
L
LINUX DO - 最新话题
S
Securelist
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
Recent Announcements
Recent Announcements
S
Schneier on Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Cyberwarzone
Cyberwarzone
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
Security Archives - TechRepublic
Security Archives - TechRepublic
V
Vulnerabilities – Threatpost
T
Tor Project blog
GbyAI
GbyAI
B
Blog
博客园 - 司徒正美
博客园 - 叶小钗
Recorded Future
Recorded Future
F
Fortinet All Blogs
Spread Privacy
Spread Privacy
IT之家
IT之家
Forbes - Security
Forbes - Security
L
Lohrmann on Cybersecurity
有赞技术团队
有赞技术团队
博客园 - 聂微东
A
Arctic Wolf
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Blog of Author Tim Ferriss
N
News and Events Feed by Topic
O
OpenAI News
Apple Machine Learning Research
Apple Machine Learning Research
Help Net Security
Help Net Security
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

See you soon

哟,好久不见,无线打印 | See you soon 试试将文章版本化管理吧 | See you soon 使用 Quadlet 将 Podman 中的 Postgres 当作 systemd 服务运行 | See you soon 大他者,那个无时无刻都在盯着你的东西 | See you soon Laws of Software Engineering,软件工程定律 | See you soon 浅记多因素身份认证 | See you soon Linux 内核中的度量单位 | See you soon 重置 GPG 智能密钥 | See you soon 向 NAS 引入 samba | See you soon 无法重复键入的 Fcitx5 | See you soon ZFS 降级事故 | See you soon 记被 XanMod Kernel 和 AppArmor 联合坑的一次踩坑 | See you soon agent 的 skill 与 toolcall | See you soon 记一次服务器被挂恶意挖矿二进制 | See you soon 活着的 Arc | See you soon 令 acme.sh 使用 Cloudflare 的 DNS API 签发与续签证书 | See you soon 于 Tokio 中卸载 CPU Bound 任务 | See you soon 如我所见,梦破碎的时候 | See you soon 74LS 家族手册 | See you soon JDK Projects 备忘录 | See you soon 关于历史 | See you soon 用 curl 下载 OnePlus 的 ROM | See you soon 实用命令切片 | See you soon 再见,Oh My Zsh。 | See you soon 你不应该复用 strings.Builder | See you soon 博客的明日 | See you soon 被 AppArmor 击杀的 Dockge | See you soon AI 时代的自我 | See you soon 支持删除的布隆过滤器 | See you soon RVA23 包含了什么 | See you soon Rust 的边界检查是否已经有很大的进步 | See you soon 使用 Rust 编写操作系统:Barebones | See you soon 使用 Rust 编写操作系统:引言 | See you soon 编译器笔记:rope | See you soon 编译器笔记:CST | See you soon Paradoxical 札记 | See you soon 简单的相似去重算法(基于向量) | See you soon 更加现代的 PaperMC Minecraft 插件设计指南 | See you soon 简单的 CFG 语法分析方法 | See you soon 简单地使用 Caddy 实现 CORS 配置 | See you soon 让 OpenCV 可以被静态链接 | See you soon 图片搜索笔笺 | See you soon 电路板设计笔记-保护 | See you soon 使用 Rust 实现 SnowflakeId | See you soon 农夫乐事 FaQ 启示 | See you soon 使用 Rust 实现拓展系统札记 | See you soon 遗传学定律的代码实现 | See you soon EN:The Journey of Rust and Procps | See you soon ZH:Rust 与 Procps 之旅 | See you soon 使用 debootstrap 与 schroot 构建一个纯净环境 | See you soon GPG添加新的用户信息 | See you soon GSoC2024 笔记:使用 Rust 重新实现 procps | See you soon JWT 小册 | See you soon 使用密钥登录 SSH | See you soon Guava:Cache | See you soon 编译器笔记:增量编译 | See you soon Gradle秘境:添加一个类似modCompileOnly的依赖块 | See you soon Minecraft:原始经济系统设计简述 | See you soon TinyRemapper笔记 | See you soon MicroOS:进阶 | See you soon MicroOS:起步 | See you soon Swapfile 指北 | See you soon GPG 物理密钥的安装与密钥的迁移 | See you soon 用GPG签名告诉大家这就是我的提交 | See you soon DFS:深度优先搜索 | See you soon 文章翻译:从init.vim到init.lua | See you soon 目录遍历攻击 | See you soon 如何挂载.img文件,以及如何使用QEMU模拟arm64环境 | See you soon 在树莓派上编译 OpenCV | See you soon 关于卸载BlueStacks后遇到的问题 | See you soon
基于栈的虚拟机与基于寄存器的虚拟机 | See you soon
Krysztal Huang · 2025-07-20 · via See you soon

基于栈的虚拟机与基于寄存器的虚拟机

经常听到 LuaJIT 和 JVM 分别是基于寄存器的虚拟机和基于栈的虚拟机,那么这两种虚拟机究竟有什么区别?

最主要的区别

既然都叫作虚拟机了,那么实际上这些 Runtime 的最终目的是模仿实体机提供一个可以跨平台运行的环境。

基于寄存器的操作

读过计组和 CSAPP 的朋友们都知道,我们的 x86 机器指令存在一个东西叫作 N 地址指令,他看起来像是这样

  • N=3: ADD a, b, c
  • N=2: ADD a, b

ADD 指令后的地址就是目标的地址,并且 ADD 命令在完成后会在某个寄存器/内存里放入这次运算的值。经典的 x86 采用的是二地址指令,会在某个寄存器里放入这个值

基于栈的操作

那么如果我们的 N 地址 N=0 会发生什么?看起来我们没有任何地址可以存放读取。

但如果我们引入一个数据结构来储存值,操作数仅仅能操作当前最新的值会发生什么?基于栈的虚拟机就产生了。

求值栈

我们引入一个栈式结构叫作求值栈,并且假定有如下的命令

iconst_1

iconst_2

iadd

istore_0

iconst_1iconst_2 中我们压入了两个整型值:12

然后我们使用了 iadd 命令,iadd 命令将会弹出栈顶的两个整型值,并且将其相加后压入栈顶,这样我们的求值栈就只有一个值 2

在完成以上求值后,我们使用了 istore 命令将求值栈最终的值放到局部变量区的 0 号位

  • istore, istore_<n>: An istore instruction with operand Index is type safe and yields an outgoing type state NextStackFrame, if a store instruction with operand Index and type int is type safe and yields an outgoing type state NextStackFrame.
  • iadd: An iadd instruction is type safe iff one can validly replace types matching int and int on the incoming operand stack with int yielding the outgoing type state.

这样看起来就非常的跨平台,因为到目前为止几乎完全不用和平台的寄存器交互,这几乎完全是模拟出来的行为

如果要用 x86 汇编的话,两条指令就可以了:

请注意,求值栈(Evaluate Stack)不是一个固定的名字,除了求值栈,还可以叫作表达式栈(Expression Stack)

各有优劣?

简单列个表会更直观一些

请注意,设计模式并不是固定的,例如 JVM 的 JIT 也会面向平台进行特化,这一步实际上也是走向基于寄存器的虚拟机的设计模式,因为这样很明显会更快

基于栈的虚拟机基于寄存器的虚拟机理由
可移植性基于寄存器的虚拟机由于需要考虑和本地机器的映射关系,因此需要花很大力气去整理映射关系,但基于栈的虚拟机不需要这层映射关系
实现难易度简单同上
性能较慢快速基于寄存器的虚拟机由于存在和本地机器的寄存器映射关系,因此运行起来非常的高效,基于栈的虚拟机有额外开销
储存资源占用较低较高由于基于栈的虚拟机使用的是零地址指令,它的占用比其他任何指令都小并且更加紧凑。所以基于栈的虚拟机对于硬盘占用会更小

参照