本章咱们将进入处理器体系结构介绍的神秘海洋中,咱们熟悉的手机,电脑等设备的中心硬件都离不开处理器。处理器能够称的上是人类创造的最杂乱的体系之一,一块手指大小的硅片,能够容纳一个完好的高性能处理器、大的高速缓存,以及用来衔接外部的逻辑电路。而且由于摩尔定律,从性能上讲,今日一块芯片上的处理器,现已使得三十年前比房间那么大的超级核算机都相形见绌了。

  那么可能有人会问,咱们软件开发者,永久都不会自己去规划处理器,那咱们为什么要学习处理器的完结?

  ①、首要处理器的规划对错常有趣而且重要的,处理器规划包含许多好的工程实践原理,它需要完结杂乱的使命,而结构又要尽可能的简略和规矩,咱们去了解事物是怎样作业的有其内在的价值。

  ②、处理器是整个核算机能正常作业的重要组成部分,了解处理器怎样作业能帮助咱们了解整个核算机怎样作业。

  ③、尽管咱们不用去规划处理器,可是咱们作业的产出许多都是在包含处理器的硬件体系上运转的,了解它能让咱们作业更有功率。

  咱们知道核算机体系底层硬件只识别机器言语,而处理器便是用来履行一系列指令,每条指令履行某个简略的操作。比方两个数相加,汇编指令 ADD 会被编码为一个或多个字节组成的二进制格局。

  这里一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构(Instruction-Set Architecture,ISA)。

  而不同的处理器宗族,比方Intel IA32、IBM/Freescale PowerPC和AMD处理器宗族,都有不同的ISA。这和咱们上一章讲的汇编言语是直接面向处理器(Processor)的程序规划言语,不同类型的CPU 有不同的机器指令体系,也就有不同的汇编言语是相同的。不同的处理器,其指令集体系结构也不相同,也便是说一个程序编译成在一种机器上运转,就不能在别的一种机器上运转,怎样处理这种兼容性问题呢?ISA 在编译器编写者和处理器规划人之间提供了一个抽象概念层,编译器编写者只需要知道允许哪些指令,以及它们是怎样编码的;而处理器规划者有必要建造出这些指令的处理器。

1、Y86指令

  本篇博客咱们首要解说的是Y86指令体系结构。首要咱们要知道的是Y86指令是不存在的,这是本书的作者受到 IA32指令,也便是“x86”的启发,所设想出来的一种处理器体系结构,与 “x86” 比较,Y86指令集的数据类型、指令和寻址方法都要少一些,字节级编码也比较简略。可是它仍然足够完好,能够写一些简略的处理证书的程序,而规划一个Y86处理器要求咱们面对许多处理器规划者同样面临的问题。所以学习Y86处理器的规划是很有必要的。

  定义一个指令集体系结构,会包含定义各种状况元素,指令集和它们的编码、一组编程规范和反常处理事件。

  Y86程序中的每条指令都会读取或许修正处理器状况的某些部分,这便称为程序员可见状况,这里的程序员既可所以用汇编代码写程序的人,也可所以发生机器级代码的编译器。在处理器完结中,只需咱们确保机器级程序能够访问程序员可见部分,就不需要完全按照ISA 隐含的方法来表示和组织这个处理器状况。

  和IA32相同,Y86程序员可见部分包含:寄存器、存储器、条件码、PC(程序计数器)、程序状况。

  在Y86傍边,寄存器也是有8个,每一个寄存器能够存储一个字,也便是一个32位二进制。条件码是一个一位二进制的寄存器,保存着最近的算术或逻辑运算所形成的影响的信息。PC则是程序计数器,记录当时正在履行的指令的地址。存储器则是一个很大的字节数组,保存着程序和数据,Y86的程序能够运用虚拟地址(类似于数组的下标)来访问存储器,硬件和操作体系会将虚拟地址翻译为实践的地址。最后一个程序状况(stat),它则代表着程序的运转状况。它会指示程序是否正常运转,或许发生了某个特别事件。

  下图是 Y86 ISA 各个指令的描述,左边是指令的汇编码表示,右边是字节编码。它只包含四字节整数操作。

深入理解计算机系统(4.1)------Y86指令集体系结构

  halt :这个指令会停止指令的履行。在IA32中有个与之相当的指令 hlt,不过IA32的应用程序不允许运用这条指令,由于它会导致整个体系暂停运转。而关于Y86来讲,履行 halt 指令会导致处理器停止,并将状况码设置为 HLT。

  nop:这是一个占位指令,它不做任何事情,后续为了完结流水线,它有必定的作用。

  xxmovl:这是一系列的数据传送指令,其间r代表寄存器,m代表存储器,i代表立即数。比方rrmovl指令,则代表将一个寄存器的值,赋给别的一个寄存器。

  OPl:这包含4个整数操作指令,addl、subl、andl和xorl。他们只对寄存器数据进行操作。

  jXX:包含7个跳转指令,jmp,jle,jl,je,jne,jge,jg。根据分支指令的类型和条件码的设置来选择分支。

  cmovXX:包含6个条件传送指令,cmovle,cmovl,cmove,cmovne,cmovge和cmovg,只发生在两个寄存器之间,不会将数据传送到存储器。

  call:指令将回来地址入栈,然后跳到意图地址。

  ret:call是过程调用,ret是回来。将回来地址入PC,并跳到回来地址。

  pushl和popl:指令完结了地址的入栈和出栈

2、指令编码

  指令集的一个重要性质便是字节编码有必要要有仅有的解说。任何一个字节序列要么是一个仅有的指令序列的编码,要么就不是一个合法的字节序列。

  Y86就具有这个性质,由于每条指令的第一个字节有仅有的代码和功用组合,给定这个字节,咱们就能够决议一切其他附加字节的长度和含义。这个性质确保了处理器能够无二义性的履行方针程序代码。即便代码嵌入在程序的其它字节中,只需从序列的第一个字节开端处理,咱们仍然能够很简单的确认指令序列。反过来,如果不知道一段代码序列的起始位置,咱们就不能准确的确认怎样将序列划分为独自的指令。关于试图直接从方针代码字节序列中抽取出机器级程序的反汇编程序和其它一些东西来说,就带来了困难。

  关于如下两个图:

  下图是整数操作、条件传送和分支指令的详细编码:

深入理解计算机系统(4.1)------Y86指令集体系结构

下图是8个程序寄存器对应的标识符ID

深入理解计算机系统(4.1)------Y86指令集体系结构

咱们应该怎样确认指令 rmmovl %esp,0x12345(%edx)的字节编码?

  首要最最上面的一幅图,咱们能够看到rmmovl 的第一个字节是40,。源寄存器%esp应该编码放在rA字段中,而基址寄存器%edx 应该编码放在 rB 字段中,本博客的第三幅图咱们知道这两个寄存器的标识符ID为42。最后偏移量编码放在4字节的常数中,咱们在0x12345的前面填上0变为4个字节,也便是字节序列 00 01 23 45,写成按字节反序便是 45 23 01 00。所以整个衔接起来便是:404245230100

3、Y86反常

  关于Y86来说,程序员可见的状况中包含stat状况码,它标识了程序履行的状况。这个状况码的可能值如下:

深入理解计算机系统(4.1)------Y86指令集体系结构

关于Y86,当程序遇到反常时,咱们就简略的让处理器停止履行指令。可是在更完好的规划中,处理器通常会调用一个反常处理程序,这个过程被指定用来处理遇到的某种类型的反常。

4、总结

  本篇博客咱们简略介绍了Y86的指令集结构,相对而言不难了解。后边将会介绍详细的逻辑规划和硬件控制言语HCL。