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

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

  那么可能有人会问,我们软件开发者,永远都不会自己去设计处理器,那我们为什么要学习处理器的实现?

  ①、首先处理器的设计是非常有趣而且重要的,处理器设计包括很多好的工程实践原理,它需要完成复杂的任务,而结构又要尽可能的简单和规则,我们去了解事物是怎样工作的有其内在的价值。

  ②、处理器是整个计算机能正常工作的重要组成部分,理解处理器如何工作能帮助我们理解整个计算机如何工作。

  ③、虽然我们不用去设计处理器,但是我们工作的产出很多都是在包含处理器的硬件系统上运行的,了解它能让我们工作更有效率。

  我们知道计算机系统底层硬件只识别机器语言,而处理器就是用来执行一系列指令,每条指令执行某个简单的操作。比如两个数相加,汇编指令 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 各个指令的描述,左边是指令的汇编码表示,右边是字节编码。它只包括四字节整数操作。

  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就具有这个性质,因为每条指令的第一个字节有唯一的代码和功能组合,给定这个字节,我们就可以决定所有其他附加字节的长度和含义。这个性质保证了处理器可以无二义性的执行目标程序代码。即使代码嵌入在程序的其它字节中,只要从序列的第一个字节开始处理,我们仍然可以很容易的确定指令序列。反过来,如果不知道一段代码序列的起始位置,我们就不能准确的确定怎样将序列划分为单独的指令。对于试图直接从目标代码字节序列中抽取出机器级程序的反汇编程序和其它一些工具来说,就带来了困难。

  对于如下两个图:

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

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

  我们应该怎么确定指令 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状态码,它标识了程序执行的状态。这个状态码的可能值如下:

  对于Y86,当程序遇到异常时,我们就简单的让处理器停止执行指令。但是在更完整的设计中,处理器通常会调用一个异常处理程序,这个过程被指定用来处理遇到的某种类型的异常。

4、总结

  本篇博客我们简单介绍了Y86的指令集结构,相对而言不难理解。后面将会介绍具体的逻辑设计和硬件控制语言HCL。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏服务端技术杂谈

线程池监控

通过扩展线程池进行监控,通过继承线程池并重写线程池的beforeExecute,afterExecute和terminated方法,我们可以在任务执行前,执行后...

751
来自专栏微信公众号:Java团长

Java中的锁原理、锁优化、CAS、AQS

结论:如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。

571
来自专栏编程

PHP7 下的协程实现

前言 相信大家都听说过『协程』这个概念吧。 但是有些同学对这个概念似懂非懂,不知道怎么实现,怎么用,用在哪,甚至有些人认为yield就是协程! 我始终相信,如果...

2108
来自专栏你不就像风一样

高并发下的Java数据结构(List,Set,Map,Queue)

由于并行程序与串行程序的不同特点,适用于串行程序的一些数据结构可能无法直接在并发环境下正常工作,这是因为这些数据结构不是线程安全的。本节将着重介绍一些可以用于多...

422
来自专栏坚毅的PHP

java.util.concurrent 在shorturl项目中的应用

问题:微博短链项目应用到哪些concurrent包中的类,类的用途是什么?场景是怎样?效果? java.util.concurrent.atomic.Atomi...

3165
来自专栏IT技术精选文摘

Java内存模型

在多核时代,如何提高CPU的性能成为了一个永恒的话题,而这个话题的讨论主要就是如何定义一个高性能的内存模型,内存模型用于定义处理器的各层缓存与共享内存的同步机制...

18510
来自专栏Java成长之路

Java内存模型

多任务处理在现代计算机操作系统中几乎已经是一项必备的功能了。计算机cpu的运算速度与它的存储和通信子系统速度的差距太大,大量的时间都花费在磁盘I/O、网络通信或...

521
来自专栏后台全栈之路

基于汇编的 C/C++ 协程 - 切换上下文

既然本系列讲的是基于汇编的 C/C++ 协程,那么这篇文章我们就来讲讲使用汇编来进行上下文切换的原理。

2026
来自专栏IT技术精选文摘

Java多线程知识小抄集(三)

51. SimpleDateFormat非线程安全 当多个线程共享一个SimpleDateFormat实例的时候,就会出现难以预料的异常。 主要原因是parse...

1836
来自专栏阿杜的世界

《七周七并发模型》阅读笔记(一)一、线程与锁——第一天二、线程与锁——第二天三、线程与锁——第三天

线程与锁模型其实是对底层硬件运行过程的形式化,这种形式化既是该模型最大的优点,也是它最大的缺点。我们借助Java语言来学习线程与锁模型,不过内容也适用于其他语言...

562

扫码关注云+社区