深入理解计算机系统(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 条评论
登录 后参与评论

相关文章

来自专栏架构说

Effective STL(21) 永远让比较函数对相同元素返回false

问题描述: 昨天一哥们些的程序,在定义比较函数的时候是这样写的 bool cmp(const T& a, const T& b) { if (a >=...

3469
来自专栏noteless

[零]java8 函数式编程入门官方文档中文版 java.util.stream 中文版 流处理的相关概念

https://docs.oracle.com/javase/8/docs/api/

771
来自专栏CDA数据分析师

教你一招:用 50 行 Python 代码制作一个计算器

简介 在这篇文章中,我将向大家演示怎样向一个通用计算器一样解析并计算一个四则运算表达式。当我们结束的时候,我们将得到一个可以处理诸如 1+2*-(-3+2)/5...

1847
来自专栏Vamei实验室

纸上谈兵: 堆 (heap)

堆(heap)又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。回忆一下,在队列中,我们可以进行的限定操作是dequeue和en...

1957
来自专栏AndroidTv

分享两个提高效率的AndroidStudio小技巧

这次分享两个 Android Studio 的小技巧,能够有效提高效率和减少犯错,尤其是在团队协作开发中。

41013
来自专栏FreeBuf

适用于IDA Pro的CGEN框架介绍

一切都始于我想要分析一些MeP代码的时候。我通常在IDA Pro中做逆向工作,但是有一小部分处理器IDA并不支持。幸运的是,objdump可以支持这些小众的处理...

1977
来自专栏PPV课数据科学社区

工具 | 如何在Python中调用R语言包?

R语言是非常强大的做统计分析和建模方面的开源软件,它有非常丰富的统计软件包,做统计可以说只有你想不到的,没有R办不到的。Python又是当下最流行的编程软件之一...

5418
来自专栏desperate633

设计模式之生成器模式(Builder Pattern)生成器模式的优缺点生成器模式的实际应用生成器模式与工厂模式的不同

虽然我们具体在构建一台主机的时候,每个对象的实际步骤是不一样的,比如,有的对象构建了i7cpu的主机,有的对象构建了i5cpu的主机,有的对象构建了普通键盘,有...

542
来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版5.1节C风格数据结构内存布局之引言

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

431
来自专栏python学习路

二、Python介绍

Python 是一门什么样的语言? python是一门动态解释性的强类型定义语言。 编程语言主要从以下几个角度为进行分类,编译型和解释型、静态语言和动态语言、...

2784

扫码关注云+社区