Y86指令集(介绍篇)
2014-06-13
Y86的模拟器、汇编器是我们的一项作业。我决定写几篇博客来梳理一些关于它的技术要点。
基本特性
Y86出自《深入理解计算机系统》(CSAPP)第四章。它是一个极为简化的、用于教学的CPU指令集,在特性上与目前PC平台主流的x86相近。
它包括:
- 八个32位的通用寄存器,就像在x86上那样;
- 指令地址寄存器,类似于
EIP,不过在Y86中我们将它称为PC; - 地址从0开始的内存;
- 状态:正常运行、地址错误、指令错误、停机;
- 三个Flags,分别对应x86中的ZF、SF、OF,表示结果为零、为负数、溢出;
- 数据移动、计算、堆栈维护等指令(当然,比x86的指令集简单得多)。
但是它:
- 不包含x87(FPU)、MMX、SSE、SSE2、SSE3……SSE233(误)等各种指令集;
- 不区分实模式和保护模式,始终在32位下工作;
- 没有中断,没有系统调用;
- 没有x86风格的调试支持,模拟器中允许运行指定步数停机;
- 没有IO(嗯…你可以猜一下什么东西取代了IO);
- 比x86更宽松、更整齐的二进制格式。

下面来说说Y86中的那些指令——
指令:计算与无条件mov
计算和mov应该说是Y86中最基本的指令了。
Y86的计算指令只允许操作寄存器,有addl,subl,andl,xorl这四个。
mov在x86中是一组同名的指令,而在Y86中,为了方便汇编器的编写,使用了四个不同的名字:
rrmovl是寄存器之间的数据移动;irmovl将立即数移入寄存器;rmmovl将寄存器的值移到另一个寄存器加偏移表示的内存地址,形如rmmovl rA, D(rB);mrmovl和rmmovl相对,将内存中的值移到寄存器,mrmovl D(rB), rA。
指令:条件
Y86中的条件跳转只允许跳转到固定的绝对地址。
类似于x86,Y86的跳转有jmp,jle,jl,je,jne,jge,jg这七种,jmp相当于条件永远为真。
条件数据移动指令与跳转指令一一对应,rrmovl可以看成和jmp一样的“永真条件”,而六种cmovXX分别和对应的jXX使用相同的判断条件。
指令:堆栈与调用
Y86和x86一样,ESP寄存器表示栈顶。因此有pushl rA和popl rA这两条指令用于进出栈。
pushl先向内存中写数据再移动ESP,而popl先移动ESP再从内存中读数据。……慢着,这顺序区别有什么关系吗?还真有,如果遇到pushl %esp或者popl %esp这样的指令,这个顺序将影响结果。
call即调用,在执行跳转前将PC压栈。
ret即返回,弹出PC。这条指令有一个特殊的地方,它是唯一允许跳转到任意地址的指令,这会给模拟器的实现带来一些麻烦。
之后,我们会继续介绍Y86的模拟器实现。