内存布局
- Register 16bit宽度
- RAM8,8个Register组成,一个3选8,地址为3位
- RAM64,8个RAM8组成,加一个3选8,地址位6位
- RAM512,8个RAM64组成,加一个3选8,地址位9位
- RAM4K,8个RAM512组成,加一个3选8,地址位12位
- RAM16K,4个RAM4K足层,加一个2选4,地址位14位
单个RAM16K的总数据大小为 2^14 = 16384
16bit指令,其中1bit位标志位,所以A指令最大声明的内存地址为 2^15 = 32768
整个Memory由RAM16K、SCREEN、KBD三部分组成,各个部分的地址范围为:
- RMA16K 0-16383(16K)
- SCREEN 16384-24575(8K)
- KBD 24576(16Bit)
其中RAM16K的划分为:
- 0 SP(存储栈指针,也就是下一条指令所操作的Stack的地址)
- 1 LCL(存储函数局部变量基址,关于LCL的使用方法见 函数声明与调用)
- 2 ARG(存储call指令调用函数时参数的基址,关于ARG的使用方法见 函数声明与调用)
- 3 THIS(用于指向jack中的class地址)
- 4 THAT(用于指向jack中的class地址)
- 5-12 Temp(存储jack编译到VM Code时的中间变量)
- 13-15 Generic(存储一些无特定目标的值,例如存储VM Code编译至asm时的中间变量)
- 16-255 Static(Jack Object中的static variables,这些值需要在整个class中全局可见)
- 256-2047 Stack(栈空间)
- 2048-16383 Heap(堆空间)
内存访问
push/pop指令有8中操作目标:
- local
- argumant
- this
- that
- temp
- static
- constant
- pointer
其中local、argument、this、that均存储基址,使用时加上偏移量即可得到真实内存地址。
static 与 temp 也是将值读写到对应内存上,但与前5种目标不同,static与temp的基址是固定的,分别为5与16,而前五种的基址需要读取相应内存才能确定。
constant 用于操作数字常量(字面量),没有专用内存,直接将值push/pop到stack上。
pointer 通过push/pop pointer x指令的x值判断使用THIS还是THAT,例如为0,则使用THIS,那么push pointer 0实际操作就是将当前THIS指针的值push到stack上。