我正在阅读和学习《计算机系统要素》,但我卡在了一个点上。可以在这里找到跳过下5条指令的示例章节。
无论如何,我正在尝试实现一个虚拟机(或字节码到汇编代码的翻译器),但我卡在了跳过下5条指令的一点上。
您可以在这里找到汇编符号。
目标是实现一个翻译器,将特定的字节码翻译成这个汇编代码。
我已经成功地为字节码做了一个例子:
push constant 5
被翻译成:
@5
D=A
@256
M=D
正如我所说的那样,Hack的汇编语言可以在我提供的链接中找到,但基本上是:
@5 // Load constant 5 to Register A
D=A // Assign the value in Reg A to Reg D
@256// Load constant 256 to Register A
M=D // Store the value found in Register D to Memory Location[A]
这很直截了当。根据定义,内存位置256是堆栈的顶部。
push constant 5
push constant 98
将被翻译为:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
这一切都很好...
我还想再举一个例子:
push constant 5
push constant 98
add
被翻译成:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
@257 // Here starts the translation for 'add' // Load top of stack to A
D=M // D = M[A]
@256 // Load top of stack to A
A=M // A = M[A]
D=D+A
@256
M=D
我认为这很清楚。
但是我不知道如何翻译字节码。
eq
转换为汇编语言。eq 的定义如下:
三个指令(eq,gt,lt)返回布尔值。VM将true和false分别表示为-1(负一,0xFFFF)和0(零,0x0000)。
因此,我需要弹出两个值分别到寄存器A和D中,这很容易。但是我应该如何创建一个汇编代码来检查值并在结果为真时推送1或在结果为假时推送0?
Hack计算机支持的汇编代码如下:
push constant 5
push constant 6
sub
如果堆栈中推送的两个值相等,则其将保持值0,否则为!0,但这有什么帮助呢?我尝试使用D&A或D&M,但那也没有什么帮助。
我还可以引入条件跳转,但我怎么知道要跳转到哪个指令?Hack汇编代码没有像“跳过接下来的5条指令”之类的东西。
[由Spektre编辑]目标平台摘要,就我所见
- 16位冯·诺依曼体系结构(地址为15位,具有16位字访问)
- 数据存储器32KW(读/写)
- 指令(程序)存储器32KW(只读)
- 本地16位寄存器A、D
- 通用16位寄存器R0-R15映射到数据存储器的0x0000-0x000F
- 这些很可能也用于:
SP(R0),LCL(R1),ARG(R2),This(R3),That(R4)
- 屏幕映射到数据存储器的0x4000-0x5FFF(512x256黑白像素8KW)
- 键盘映射到数据存储器的0x6000(ASCII码,如果最后按下的键?)
Z,C
来完成的,有些还包括条件分支(主要是MCU)。所以cmp a,b
通常执行a-b
,但会丢弃结果并留下标志。现在根据条件(无论是跳转还是其他指令)进行判断,相等=(Z),大于=(NC),小于=(C)
。