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

“Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.” ―Linus Torvalds

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

课程的 Part I:

被抽象成一块 Hack 器件,Part II 的重点在软件部分,包括高级语言(Jack)、操作系统、编译器(Jack Compiler)和 虚拟机翻译器(VM translator)。

One tier VS Two tier

我们这篇文章来看 VM Code 和 VM Translator 的实现,后面的文章会看 Two tier 的高级语言 Jack 和 Jack 编译器。

VM Code

编译器把高级语言编译成 vmcode,而 vmcode 被设计成在堆栈结构机器(abstract stack machine)运行。

对于上面的数学计算,Stack 都可以通过 pop x y 然后 command x y (实现上不同的 command 用不同汇编语言实现,然后硬编码在 VM translator 里) 最后 push x y 的计算结果回到 stack,如下图:

Segments

我们现在知道了 vmcode 是如何计算的,但是高级语言里的计算结果是存储在不同的变量里的,所以我们还需要让 vmcode 也知道这些变量的种类。

所以 vmcode 有了 segment 的概念,不同的变量放在不同的 segment 里面,比如函数的参数放在 argument 段里,static 变量放在 static 段里,所以汇编器里的一些与定义符号其实对应的就是 vmcode 里不同的段,这些段都是虚拟的,实际上都在一块 RAM 里。

constant

比如程序里有一段 const int x = 17 17 就放在 constant segment 里,我们来看看 vmcode 如何把 17 放进 constant segment 里,以及对应的汇编代码,因为我们这节课实现的是 VM translator,生成 VM code 是后面我们要实现的 compiler 要做的事情。

上面的图展示了,push constant 17 (把 17 放到 stack machine 的 constant segment 里)的过程。但是注意,这里实际上没有一个 constant segment,因为 constant 的语义就是把一个常数放进 stack 里。

local | argument | this | that

这几个段虽然功能不同,但都可以用同样的方式操作,只是段的位置不一样,所以语义不同,但都可以用相同的伪代码表示(下面是 local 的图,其他不同之处把 LCL 替换成 ARG THIS THAT 即可,这些预定义符号代表段在 RAM 里的开始地址),pop segment i 的语义是:把最新 push 到 stack 里的值 pop 到对应 segment 里的 segment start address + i 位置供程序使用。push segment i 的语义是:把 segment 里的 segment start address + i 位置的值 push 到 stack 的 SP 位置供程序使用。

static

RAM[16] - RAM[255] 用来存放 static 变量

每个 filename.vm 文件的静态变量,存放在 RAM 里,相当于每个 vm 文件有一个虚拟的 segment,每个 segment 的名字是汇编语言里的标签 filename.i。

temp

temp 变量放在 RAM[5] - RAM[12],这里编译器生成 VM code 会用来存一些临时信息,后面的文章会介绍。

pointer

push/pop pointer 0 等于 push/pop THIS

push/pop pointer 1 等于 push/pop THAT

有了上面的这些信息,我们就可以编写代码,把这些 VM Code 翻译成汇编语言。

VM code 里还有分支和函数调用的概念,下篇文章,我们看如何把这些概念翻译成汇编语言。

相关推荐

  1. 计算机基础1

    2024-03-30 07:18:05       47 阅读
  2. 计算机基础1-汇编基础

    2024-03-30 07:18:05       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-30 07:18:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-30 07:18:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-30 07:18:05       82 阅读
  4. Python语言-面向对象

    2024-03-30 07:18:05       91 阅读

热门阅读

  1. C# 打印输出以及文件输入输出

    2024-03-30 07:18:05       43 阅读
  2. 【C# 懒人必备技能】反射

    2024-03-30 07:18:05       35 阅读
  3. 设计模式 - 命令模式

    2024-03-30 07:18:05       42 阅读
  4. css实现鼠标放上去半透明光片划过效果

    2024-03-30 07:18:05       38 阅读
  5. 服务未注册到nacos通过gateway转发的配置

    2024-03-30 07:18:05       38 阅读
  6. MYSQL中update的low_priority

    2024-03-30 07:18:05       37 阅读
  7. 机器学习 - 提高模型 (代码)

    2024-03-30 07:18:05       37 阅读