Nand2Tetris中VM语言如何访问屏幕与键盘内存映射?
Nand2Tetris虚拟机语言访问屏幕/键盘内存映射的实现方式
核心内存映射地址
- 屏幕内存映射起始于16384(0x4000),共8192个连续地址,对应屏幕256x512像素的每个点(值为1时像素为黑,0为白)。
- 键盘的内存映射固定在24576(0x6000),该地址存储当前按下按键的键码,无按键时值为0。
VM语言直接访问内存映射的方法
VM的虚拟内存段(local/arg/this/that/temp等)无法直接指向屏幕/键盘区域,必须通过物理地址直接操作,核心是借助pointer寄存器间接读写:
单个地址读写(对应Memory.peek/poke)
比如读取屏幕第720个偏移位置的像素(对应物理地址16384+720=17104):
push constant 17104 // 加载目标物理地址 pop pointer 1 // 将地址存入THAT寄存器(pointer 1关联THAT) push that 0 // 读取该地址的值到栈顶
往屏幕第120个偏移位置写入值74(物理地址16384+120=16504):
push constant 74 // 准备要写入的值 push constant 16504 // 目标物理地址 pop pointer 1 // 把地址存入THAT pop that 0 // 将值写入对应内存地址
系统调用的底层实现(比如Output.printString)
Jack标准库的Output.printString这类功能,底层VM代码会直接操作屏幕内存映射完成字符渲染:
- 先获取待打印字符串的起始地址(通常存储在
this或其他虚拟段中)。 - 循环读取每个字符的ASCII值,匹配预定义的字符字形像素模板,计算对应屏幕上的像素地址。
- 逐个写入像素值完成字符绘制,同时更新屏幕光标地址,定位到下一个字符的绘制位置。
你看到Jack编译后的VM代码里只会有call Output.printString 1这类调用,是因为实际的内存操作逻辑被封装在Jack标准库的VM实现文件(比如Output.vm)里,需要查看这些库文件才能看到具体的物理地址访问代码。
内容的提问来源于stack exchange,提问作者kalyan chakravarthy
相关产品推荐
相关产品推荐

