07. VM I: Stack Arithmetic
术语
虚拟机(Virtual Machine)高级语言先被编译为中间代码,然后中间代码被转化为机器语言。中间代码运行在虚拟机上,它是一个抽象的计算机,提供了一个与底层硬件无关的编程环境。虚拟机可以在不同的硬件平台上运行相同的中间代码,从而实现跨平台的兼容性。
JVM(Java Virtual Machine)是Java语言的虚拟机实现,它将Java字节码转换为机器代码并执行。
.jack 文件经过第 9 ~ 10 章的编译器编译为 .vm 文件,然后经过第 7 ~ 8 章的 VM 翻译器翻译为 Hack 汇编代码(.asm)再经过第六章的汇编编译器编译为 Hack 二进制码(.hack)并最终在 Hack 计算机上运行。
VM 规范
9 个面向堆栈的算术命令和逻辑命令,其中 7 个是二元的:从堆栈中弹出两个元素,在其上执行操作,然后将结果压入堆栈。其余两个命令是一元的:从堆栈中弹出一个元素,在其上执行操作,然后将结果压入堆栈。
VM 分别用 -1(0xFFFF)和 0(0x0000)表示 true 和 false。
| 命令 | 返回值 | 说明 | | ---- | -------- | --------------- | ------ | | add | x + y | 整数加法 2-补码 | | sub | x - y | 整数减法 2-补码 | | neg | -x | 算术求反 2-补码 | | eq | x == y | 相等判断 | | gt | x > y | 大于判断 | | lt | x < y | 小于判断 | | and | x & y | 按位与 | | or | x | y | 按位或 | | not | !x | 按位非 |
内存访问命令 pop 和 push 操控 8 个独立的虚拟内存段(virtual segments), push segment index 将 segment[index] 压入堆栈,pop segment index 将堆栈顶元素弹出并存储到 segment[index]。
| 段名 | 功能 | 说明 |
|---|---|---|
| argument | 存储函数的参数 | 进入函数时 VM 实现机制进行动态分配 |
| local | 存储函数的局部变量 | 进入函数时 VM 实现机制进行动态分配并被初始化为 0 |
| static | 存储同一 .vm 文件中所有函数共享的静态变量 | 由 VM 实现机制为每个 .vm 文件进行分配;被 .vm 文件中的所有函数共用 |
| constant | 包含所有常数的伪段(Pesudo-segment),常数的范围为 0-32767 | 由 VM 实现机制为来模拟;该段对于程序中所有函数都是可见的 |
| this that | 通用段,能够与堆中不同区域相对应来满足各种程序编写的需求 | 任何 VM 函数都可以使用这个段来操纵堆中指定的区域 |
| pointer | 该段由两个内存单元组成,用来保存 this 和 that 段的基地址 | 任何 VM 函数可以将 pointer 0 或 1 设置到某一地址上;这相当于将 this 或 that 段联结到起始于该地址的堆区域上 |
| temp | 固定的段,由 8 个内存单元组成,用来保存临时变量 | 被任何 VM 函数用于任何用途,被程序中的所有函数共享 |