X86的孪生兄弟,Y86指令体系结构
前言
为啥我的排版还是这么丑?排版如人啊,唉.说实话,上一章的内容我没搞明白,先不管了,先放一下,个人比较喜欢鲸吞的学习方式.
正文
Y86指令体系结构
Y86是一个指令体系结构(ISA),它是一个写这本书的作者出的指令集.目的是为了让我们更加清晰地了解ISA,就像在读编译原理的时候,作者会教你做个编译器是一样的道理.
我们学这个并不是为了设计指令集,因为这种工作几乎不可能发生在我们身上还是和编译原理一样,你的工作也不太可能写一个编译器,常遭一种语言,最多就是写个小例子拿来唬唬你身边的妹子.我们的目的是为了了解CPU处理器指令以及它的工作流程,学习他的思想,这对以后你的技术之路说不定有些启发.有可能你收到了启发,就领悟了一个终极技能呢?对吧
程序员看得见的东西
计算机是一个神秘的东西,他的很多密码我们都看不到,不过有了ISA的帮忙,我们就可以了解很多计算机的秘密.比如你在写博客的时候,你的CPU到底在干嘛.
理论上讲,我们在编写一个程序的时候,我们是可以知道CPU的状态的.因为在你观察程序的汇编指令时,你可以知道当程序执行到某个地方,寄存和,存储器以及条件码寄存器等等的状态是如何的.说到底,无论寄存器,存储器还是条件码寄存器等等,都是汇编指令可以访问的处理器状态.在设计和实现一个处理器的时候,只要我们能保证机器级程序(比如汇编程序)可以正常的访问程序员可见状态(比如寄存器,存储器),那么就不需要非得按照ISA真正的方式来表示我们的处理器状态.
对于Y86来说,他的程序员可见状态就是如下几种:寄存器,存储器,条件码,PC,程序状态
在Y86当中,寄存器依旧是8个,每一个寄存器可以存储一个字,也就是一个32位二进制.条件码是一个二进制的寄存器,保存着最近的算术或逻辑运算所造成的影响的信息.PC则是成虚计数器,记录当前正在执行的指令的地址.
存储器则是一个很大的字节数组,Y86的程序可以使用虚拟地址(类似于数组的下标)来访问存储器,硬件和OS会将虚拟地址翻译为实际的地址.最后一个程序状态(stat),它代表着程序的运行情况.
以上便是咱们这些码农可见的状态,或者说机器级程序可访问的CPU状态,我们在设计和实现一个处理器的时候,就是设计一系列指令去操作这些状态.
Y86指令集
下面这个图是Y86指令集,这些指令其实都是从X86指令集上意淫来的.
上面的指令大家应该不陌生吧,下面咱们简单的把每个指令的作用过一遍:
名字 | 作用 |
halt | 这个指令将会终止指令的执行 |
nop | 这是一个占位指令,他不做任何事,后续为了实现流水线,它有一定的作用 |
xxmovl | 这是一系列的数据传送指令,其中r代表寄存器,m代表存储器,i代表立即数.比如rrmov指令,则代表将一个寄存器的值,赋给另外一个寄存器 |
opl | 操作指令,比如加法,减法等等 |
jxx | 条件跳转指令,,根据后面的条件进行跳转 |
cmovxx | 条件传送指令,后面的xx代表的是条件.特别的是,条件传送只发生在两个寄存器之间,不会将数据传送到存储器. |
call与ret | 方法的调用和返回指令.一个将返回地址入栈,并跳到目标地址.一个将返回地址入PC,并跳到返回地址. |
push和pop | 入栈和出栈操作 |
指令编码
在图的右边,是指令所占的字节数或者说编码.一般两个寄存器占用一个字节,存储器则占用四个字街,指令的编码和功能占用一个字节.因此可以看到,比如rrmovl指令,它的字长长度是2,其中第一个字节代表了指令rrmovl,第二个字节代表了两个寄存器.
对于opl,jxx,cmovxx指令来说,都有一个fn标致,占用4个二进制位(半个字节).这个便是指令的功能部分,这个是由于他们的指令编码一样,但功能有所不同所造成的.比如对于opl,就有加,减,与,异或等操作,那么它们的指令编码第一个字节就分别为十六进制的60,61,62,63.
对于寄存器的表示,是使用4个二进制位表示的,这是一个ID标志.所有的寄存器可以看做是一个寄存器文件,其中的ID标志就类似于它们的地址.对于一些只需要一个寄存器的指令来说,另一个寄存器标志位使用0xF表示.
还有的指令需要一个字的常数,比如irmovl指令,call指令等等.这种指令,将会把常数放在最后的四个字节当中,顺序按照大端法或小端法表示(与机器和OS有关).对于call指令来说,这四个字节就是一个地址,这个地址就是绝对地址,指向了存储器当中的某一个位置,这个位置存储着代码.采用绝对地址是为了描述简单,真实当中,时采取的基于PC的相对地址.
Y86异常
对Y86来说,程序员可见的状态中就有stat状态码,它标志了程序执行的状态.Y86需要有能力根据stat去做一些处理.捕获为了简单起见,这里除了正常执行之外,都将停止指令的执行.真实当中,会有专门的异常处理程序.
Y86有四种不同的状态码:AOK(正常),HTL(执行halt指令),ADR(非法地址)和INS(非法指令).
Y86程序
Y86和X86的区别在于,有的时候Y86需要两条指令来达到X86一条指令就可以达成的目的.
比如对于X86指令中的addl $4,%ecx这样的指令,由于Y86当中的addl指令不包含立即数,所以Y86需要先将立即数存如寄存器,即使用irmovl指令,然后再使用addl来处理加法运算.
总的来说,Y86就是X86的一个缩减版,他的目的就是以简单的结构来实现一个处理器,帮助我们了解处理器的设计和实现.
小小的结一下
本次主要介绍了一下X86的指令集结构.