Hack计算机所有的操作都是在RAM上进行的,它的RAM分为几个部分,每个部分有不同的功能,栈区主要用来进行算术和逻辑运算、函数调用之类的操作,RAM地址16-255用来存储VM程序的静态变量,也可以称之为静态区,所谓的静态变量就是在同一个.vm文件中所有函数共享的变量,堆区用来存放对象和数组,RAM地址0-15都有特定的用处,如下图所示
按照功能的不同将内存段分为8个虚拟内存段,所有的内存段都通过相同的两个内存访问命令(栈与内存段之间的值的转移操作)进行存取:
- push segment index
将segment[index]的值压入堆栈 - pop segment index
将栈顶元素弹出然后存入segment[index]
这张表第一次看起来会感觉不知所措,但是这些段大体可以分为四类:
- 首先最简单的是constant段(常数段),它是一个伪段,也就是没有内存空间分配,constant段只能进行push操作,用于往栈内放入常数,constant可以认为对所有的vm文件都可见
- 其次是local、argument、this、that段,这几个段的基址base由专用寄存器(LCL、ARG、THIS、THAT)来保存,对这几个段的第index个数据项的访问,应该被翻译成获取RAM中地址为(base+index)的值的访问。这四个段也可以细分为两类,local和argument段保存在栈区,在函数调用时用来保存函数参数和函数的本地变量,而this和that段保存在堆区,用来存放对象和数组,这四个段都只对同一个vm函数可见
- 再然后是pointer、temp段,这两个段不同于上面四个段,它们的段被直接映射在RAM的一个固定区域上,也就是说base是确定的,pointer的base是3,temp的base是5,pointer段是用来访问THIS和THAT的值的,temp段是用来访问RAM位置5-12的值的,对所有的vm文件都可见
- 最后是static段,用来保存静态变量,static段保存在静态区,从上一章的汇编编译器我们知道,汇编语言将变量符号替换为对应的地址,在符号表中添加(Xxx,n),n代表可使用的RAM地址,从地址16开始,正好符合对于静态变量的要求,利用这规定,使用汇编符号f.j来表示VM文件f中的每个静态变量数字j,这样同一个VM文件内的函数就共享这个静态变量f.j
各个虚拟内存段的共享性如下图所示