4.1.2 Y86-64 指令
4.1.2 Y86-64 指令
图 4-2 给出了 Y86-64 ISA 中各个指令的简单描述。这个指令集就是我们处理器实现的目标。Y86-64 指令集基本上是 x86-64 指令集的一个子集。它只包括 8 字节整数操作,寻址方式较少,操作也较少。因为我们只有 8 字节数据,所以称之为“字(word)”不会有任何歧义。在这个图中,左边是指令的汇编代码表示,右边是字节编码。图 4-3 给出了其中一些指令更详细的内容。汇编代码格式类似于 x86-64 的 ATT 格式。
下面是 Y86-64 指令的一些细节。
x86-64 的
movq指令分成了 4 个不同的指令:irmovq、rrmovq、mrmovq和rmmovq,分别显式地指明源和目的的格式。源可以是立即数(i)、寄存器(r)或内存(m)。指令名字的第一个字母就表明了源的类型。目的可以是寄存器(r)或内存(m)。指令名字的第二个字母指明了目的的类型。在决定如何实现数据传送时,显式地指明数据传送的这 4 种类型是很有帮助的。两个内存传送指令中的内存引用方式是简单的基址和偏移量形式。在地址计算中,我们不支持第二变址寄存器(second index register)和任何寄存器值的伸缩(scaling)。
同 x86-64 一样,我们不允许从一个内存地址直接传送到另一个内存地址。另外,也不允许将立即数传送到内存。
有 4 个整数操作指令,如图 4-2 中的
OPq。它们是addq、subq、andq和xorq。它们只对寄存器数据进行操作,而 x86-64 还允许对内存数据进行这些操作。这些指令会设置 3 个条件码 ZF、SF 和 OF(零、符号和溢出)。7 个跳转指令(图 4-2 中的
jXX)是jmp、jle、jl、je、jne、jge和jg。根据分支指令的类型和条件代码的设置来选择分支。分支条件和 x86-64 的一样(见图 3-15)。有 6 个条件传送指令(图 4-2 中的
cmovXX):cmovle、cmovl、cmove、cmovne、cmovge和cmovg。这些指令的格式与寄存器—寄存器传送指令rrmovq一样,但是只有当条件码满足所需要的约束时,才会更新目的寄存器的值。call指令将返回地址入栈,然后跳到目的地址。ret指令从这样的调用中返回。pushq和popq指令实现了入栈和出栈,就像在 x86-64 中一样。halt指令停止指令的执行。x86-64 中有一个与之相当的指令hlt。x86-64 的应用程序不允许使用这条指令,因为它会导致整个系统暂停运行。对于 Y86-64 来说,执行halt指令会导致处理器停止,并将状态码设置为 HLT(参见 4.1.4 节)。
| 汇编代码 | 指令指示符(1 字节) | 寄存器指示符(1 字节) | 常数字(8 字节) | 总长度 |
|---|---|---|---|---|
halt |
0:0 |
1 | ||
nop |
1:0 |
1 | ||
rrmovq rA, rB |
2:0 |
rA:rB |
2 | |
irmovq V, rB |
3:0 |
F:rB |
V |
10 |
rmmovq rA, D(rB) |
4:0 |
rA:rB |
D |
10 |
mrmovq D(rB), rA |
5:0 |
rA:rB |
D |
10 |
OPq rA, rB |
6:fn |
rA:rB |
2 | |
jXX Dest |
7:fn |
Dest(紧随指令指示符) |
9 | |
cmovXX rA, rB |
2:fn |
rA:rB |
2 | |
call Dest |
8:0 |
Dest(紧随指令指示符) |
9 | |
ret |
9:0 |
1 | ||
pushq rA |
A:0 |
rA:F |
2 | |
popq rA |
B:0 |
rA:F |
2 |
图 4-2 Y86-64 指令集。指令编码长度从 1 个字节到 10 个字节不等。一条指令含有一个单字节的指令指示符,可能含有一个单字节的寄存器指示符,还可能含有一个 8 字节的常数字。字段 fn 指明是某个整数操作(OPq)、数据传送条件(cmovXX)或是分支条件(jXX)。所有的数值都用十六进制表示