计算机基础系列 —— 虚拟机代码翻译器(2)

I believe that at the end of the century the use of words and general educated opinion will have altered so much that one will be able to speak of machines thinking without expecting to be contradicted. ------ Alan Turing

文中提到的所有实现都可以参考:nand2tetris_sol,但是最好还是自己学习课程实现一遍,理解更深刻。

这篇文章我们来看 VM code 里的分支和函数调用。

分支

vmcode 里的分支靠 label goto 和 if-goto 实现,实现起来很简单,如下图:

唯一需要注意的就是 if-goto 语句,需要让 cond = pop,翻译成汇编语句就是判断 RAM[SP] 的结果,并 pop 掉。

函数

对于 vmcode 的函数有三个重要的 symbol call、function 和 return。理解了他们就可以直接按理解翻译成对应的汇编代码,这也就是虚拟机代码翻译器做的事情。我们具体来看看这三个关键字。

call

call 用在 caller 里,用来调用 callee。caller 和 callee 都是 function。

call 主要干了三件事(记录信息):

  1. 记住 returnaddress
  2. 记住 caller 的 segment 信息(static|pointer|temp|constant 不用保存,因为函数调用不影响这些段的地址)
  3. 更改 ARG 和 LCL 确保 callee 取用正确的信息

function

function 这里为什么要压入 nVars 的变量还没有理解,结合后面的文章理解了再回来补充。大致上应该是实参和形参的关系。

return

return 主要干了三件事(恢复信息):

  1. 通过 LCL 地址,恢复 caller 的 segments
  2. 讲 stack top(返回值)返回给 caller
  3. 返回到 caller 要执行的下一条指令

引导程序代码(Bootstrap code)

我们需要 Bootstrap code 去开始执行 vmcode,就像电脑需要开机才能运行程序一样。

这里的 Symbol 都是根据 VM Translator 和 assembler 的程序定义的,你可以更改你的程序,但是相应的 Symbol 表格也需要更改,到这里虚拟机代码翻译器就实现了,实现一个虚拟机代码翻译器可以加深对函数调用的理解。这章内容也比较抽象,如果实在理解不了,可以结合文章开头的代码实现理解,会容易一些。

下篇文章我们开始介绍高级语言 Jack,并实现编译器以及操作系统。

相关推荐
我叫黑大帅5 小时前
通过eino-ext如何正常indexer RAG?
后端·面试·go
Ava的硅谷新视界6 小时前
用了一天 Claude Opus 4.7,聊几点真实感受
开发语言·后端·编程
浪客川7 小时前
【百例RUST - 010】字符串
开发语言·后端·rust
无心水8 小时前
OpenClaw技术文档/代码评审/测试用例生成深度实战
网络·后端·架构·测试用例·openclaw·养龙虾
GetcharZp9 小时前
告别 CGO 噩梦!这款“纯 Go”神器让你不用 GCC 也能调 C 库,部署快到飞起!
后端
IT_陈寒9 小时前
Redis批量删除的大坑,差点让我加班到天亮
前端·人工智能·后端
lolo大魔王9 小时前
Go语言的反射机制
开发语言·后端·算法·golang
Postkarte不想说话11 小时前
使用vLLM本地部署大模型
后端
jserTang11 小时前
手撕 Claude Code-4: TodoWrite 与任务系统
前端·javascript·后端
jserTang11 小时前
手撕 Claude Code-5:Subagent 与 Agent Teams
前端·javascript·后端