热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

20172018120155312学习《深入理解计算机系统》第四章:处理器体系结构

处理器体系结构目录教材学习内容总结Y8664指令集体系结构逻辑设计和硬件控制语言Y8664的顺序实现流水线的通用原理Y8664的流水线实现教材课后习题总结教材课后实践示例处理器体系

处理器体系结构

目录

  • 教材学习内容总结
    • Y86-64指令集体系结构
    • 逻辑设计和硬件控制语言
    • Y86-64的顺序实现
    • 流水线的通用原理
    • Y86-64的流水线实现
  • 教材课后习题总结
  • 教材课后实践示例

处理器体系结构

我们看到的计算机系统都只限于机器语言程序级。处理器执行一系列指令每天指令执行某个简单操作,它们被编码为由一个或多个字节序列组成的二进制格式。一个处理器支持的指令和指令的字节集编码成为它的指令集体系结构(ISA)。

在本章的学习中,我们的学习目标如下:

  1. 了解ISA抽象的作用
  2. 掌握ISA,并能举一反三学习其他体系结构
  3. 了解流水线和实现方式

各章节需要掌握的重点内容如下:

  1. 了解Y86-64指令集体系结构,掌握汇编指令与机器码之间的转换,学会将C代码、X86汇编代码翻译为Y86-64代码;
  2. 了解逻辑设计和硬件控制语言HCL,掌握组合电路和HCL布尔表达式;
  3. 了解SEQ顺序处理器执行的6个阶段,掌握Y86-64所有指令个阶段的处理情况;
  4. 了解SEQ硬件结构,掌握分析硬件结构图的方法,以及某个寄存器的HCL描述;
  5. 了解流水线的通用原理,处理冲突和冒险的方法。

返回目录

Y86-64指令集体系结构

程序员可见状态

这里的程序员既可以是用汇编代码写程序的人,也可以是产生机器级代码的编译器(详见第一章图1.3编译系统)。

编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器 (Linker) → 可执行程序 (executables)

程序员可见状态为15程序寄存器(RF)、3个条件码(CC)、程序状态(Stat)、程序计数器(PC)和内存(DMEM),如下图所示:

(图2.2.1)

  • 程序寄存器:每个程序寄存器存储一个64位(即8字节)的字,这与Y86-64指令集的指令长度相匹配,它只包括8字节整数操作,称之为“字”不会产生歧义。
  • 条件码:包括ZF、SF、OF3个一位的条件码,保存着最近的算数或逻辑指令所造成影响的有关信息。
  • 状态码:表明程序执行的总体状态,一共包含 AOK、HLT、ADR、INS四种状态码,代码的值和含义如下表所示:

(2.1.2)

  • 程序计数器:存放当前正在执行指令的地址
  • 内存:是个很大的字节数组,存放程序和数据。
Y86-64指令

想要了解Y86-64指令集及其对应的编码,只要看懂下面这三个图就够了:

第一张图是Y86-64指令编码示意图,其中黄色框内的三个指令并非真实的Y86-64指令,OPq代表4个整数操作指令、jXX代表7个跳转指令、comvXX代表6个条件传送指令,其它指令如图所示:

(2.1.3)

如图所示,Y86-64指令集编码长度从1字节到10字节不等,这里我们将每字节(8位)用两个十六进制数(4位)表示,指令的详细解释如下:

1.halt指令用于停止指令的执行,执行halt会导致处理器停止,并将状态码设置为HLT。该指令占1个字节,用十六进制表示为「00」;

2.nop指令为占位指令,其作用参考NOP指令作用,这里我们不展开描述。该指令占1个字节,用十六进制表示为「10」;

3.rrmovq rA,rB指令作用是将rA寄存器中的值放入rB寄存器中。该指令占2个字节,用十六进制表示为「20 rArB」,其中“rA”、“rB”为两个代表寄存器的4比特数,要根据实际指令使用哪个寄存器来决定(其他涉及寄存器的传送指令同理),寄存器与数字编码的对应关系如下图所示:

(2.1.4)

例如:指令“rrmovq %rbx,%rcx”对应的编码为:「20 31」

4.irmovq V,rB指令作用是将立即数V放入寄存器rB中。该指令占10个字节,用十六进制表示为「30 FrB V」,其中“V”为八字节小段方式存储的立即数,像irmovq、pushq、popq这些只用到一个寄存器的指令,会将另一个寄存器指示符设为0xF,表示没有寄存器;

『例如』:指令“irmovq $15,%rbx”对应的编码为:「30F30F00000000000000」。

『数字转换计算过程』:由于“15”的十六进制表示为“F”,所以要在其前面添加15个“0”凑成八字节的值“000000000000000F”,再将其写成小端方式为:“0F000000000000”

5.rmmovq rA,D(rB)指令的作用是将rA寄存器中的值放入以“rB+D”为地址的内存单元中。该指令占10个字节,用十六进制表示为「40 rArB D」,其中“D”为八字节小段方式存储的代表偏移量的数;

『例如』:指令“rmmovq %rcx,-3(%rbx)”对应的编码为:「4013FDFFFFFFFFFFFFFF」。

『数字转换计算过程』:由于“-3”十六进制表示为“83”,扩展为八字节为“8000000000000003”,计算机中负数是用补码表示的,所以将其装换为补码为“FFFFFFFFFFFFFFD”,再将其写为小端方式为:“FDFFFFFFFFFFFFFFFF”

6.mrmovq D(rB),rA指令的作用是将以“rB+D”为地址的内存单元中的数放入寄存器rA中。与rmmovq类似,该指令占10个字节,用十六进制表示为「50 rArB D」,其中“D”为八字节小段方式存储的代表偏移量的数;

7.OPq rA,rB为整数操作指令,其作用是将寄存器rA和寄存器rB中的值做整数运算,并把结果存入rB寄存器中。该指令占4个字节,用十六进制表示为「6fn rArB」,其中fn代表指令的“功能码”,由具体执行“addq、subq、andq、xorq”中的哪条指令决定fn的值,其对应关系如下图“Y86-64指令集的功能码”所示:

(2.1.5)

所有指令的前4位编码成为指令的“代码部分”,如OPq指令中的“6”,功能值只有在一组相关指令共用一个代码时才有用(除了OPq,还有前面所提的jXX和comvXX都属于共用相同代码的指令)

8.jXX Dest为跳转指令,其作用是跳转到以Dest为地址(准确的说是逻辑地址)的代码处,根据分支指令的类型(处理器根据fn确定)和条件码的设置来选择分支。该指令占9个字节,用十六进制表示为「7fn Dest」,与OPq类似,其中fn为功能码,由具体执行“jmp、jle、jl、je、jne、jge、jg”中的哪条指令决定fn的值,其对应关系如“Y86-64指令集的功能码”所示,Dest为用小端方式表示的8字节绝对寻址方式的地址值(也可以是某个语句标号);

『例如』:下述代码中指令“jmp loop”对应的编码为:「700C01000000000000」

.pos 0x100 #Start code at address 0x100
    irmovq ……
    rrmovq ……
loop:
    rmovq ……
    addq ……
    jmp loop

『数字转换过程』:“.pos 0x100”的意思是目标代码起始地址为0x10C,即“irmovq ……”那行对应的地址为0x100,因为irmovq指令和rrmovq指令编码长度分别为10和2,所以“rrmovq ……”那行指令的地址为0x100+0xa=0x10a,“loop:”那行的地址为“0x10a+2=0x10c”,因此此处Dest的值为0x10c,用小端方式表示为“0C01000000000000”

9.cmovXX rA,rB为条件传送指令,其指令格式同rrmovq指令,不同点是只有当条件码满足需要的约束时才会更新目的寄存器的值。该指令占2个字节,用十六进制表示为「2fn rArB」;fn由具体执行“rrmovq cmovle cmovl cmove cmovne cmovge cmovg”中的哪条指令决定,其对应关系如“Y86-64指令集的功能码”所示;

10.call Dest指令的作用是将返回地址入栈,然后跳到Dest指向的目的地址。该指令占9个字节,用十六进制表示为「80 Dest」,其中Dest的作用类似于条件跳转指令;

11.ret指令的作用是从call指令的调用中返回。该指令占1个字节,用十六进制表示为「90」;

12.pushq rA为入栈指令,其作用是将rA寄存器中的值压入栈顶。该指令占2个字节,用十六进制表示为「A0 rAF」;

13.popq rA位出栈指令,其作用是将栈顶元素弹出到rA寄存器中。该指令占2个字节,用十六进制表示为「B0 rAF」。

应用部分

为了检验我们是否掌握了Y86-64指令与指令编码之间的转换方法,我们可以尝试着做做教材练习题4.1和4.2。这里将字节序列转换为Y86-64指令的方法总结如下:

  1. 通过代码部分确定指令长度,从而以指令为单位划分字节序列;
  2. 通过功能部分确定具体的指令;
  3. 通过寄存器指示符字节确定指令中涉及的寄存器;
  4. 通过转换数值部分以小段法编码的数字来确定立即数、偏移量、绝对地址等值。

进一步的,为了学会写Y86-64程序,我们可以从“改编x86-64汇编代码”入手,但是这里有几点需要注意(详细转换细节请见我的课下实践博客):

  1. Y86-64中要把movq指令转换为具体的rrmovq,rmmovq,mrmovq指令;
  2. Y86-64中OPq只对寄存器数据进行操作,可以借用%r8-%r14这些寄存器,先用“irmovq”指令将立即数放入寄存器中,再进行相关计算;
  3. Y86-64中没有加载有效地址指令leaq,需要用“addq”等指令来代替其功能;
  4. Y86-64中没有比较指令“cmpq”,可以用两个寄存器存放操作数的值然后用subq命令使两数相减来设置条件码;
  5. Y86-64中没有乘指令mulq,需要用addq来替换;
  6. “movq %fs:40, %rax”指令,需要弄清楚%fs:40的含义和类型;
  7. 由于Y86-64指令集中所以操作都以8个字节为单位,所以在转换“movl,addl”这些四字节指令时要额外注意,有时需要保护高四字节的值;
  8. cltq指令:用于把%eax符号扩展到%rax,所以要先判断%eax的符号位,再决定给高四个字节置1还是0;
  9. Y86-64指令集中没有leave指令,要用“rrmovq %rbp,%rsp”+“popq %rbp”来代替。
  10. 我们常常用异或一个数本身来代替直接将其赋值为0,可以防止字符串提前以“0”结束引发的数据丢失。
  11. 为了更加深刻的领会Y86-64指令的含义和用法,可以试着做做教材练习题4.3、4.4、4.5和4.6

书中给出了一个叫做“YIS”的指令集模拟器的工具,它的目的是模拟Y86-64及其代码程序的执行,而不用试图去模拟任何具体处理器实现的行为,我们要学会使用它来调试程序、模拟在硬件运行商的结果。

参考老师的给出的实验楼资源,构建YIS步骤如下:

  1. cd ~/Code/shiyanlou_cs413(根据实际情况修改,选择自己的路径)
  2. wget http://labfile.oss.aliyuncs.com/courses/413/sim.tar
  3. tar -xvf sim.tar
  4. cd sim
  5. sudo apt-get install bison flex tk
  6. sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so
  7. sudo ln -s /usr/lib/x86_64-linux-gnu/libtcl8.6.so /usr/lib/libtcl.so
  8. make

测试YIS步骤如下:

  1. cd y86-code
  2. 进入测试代码,教材p239页代码为asuml.ys,可以通过make asuml.yo进行汇编,asuml.yo就是汇编后的结果,见教材p238。
  3. make all可以汇编运行所有代码结果

返回目录

逻辑设计和硬件控制语言HCL

为实现一个数字系统需要三个主要的组成部分:计算对位进行操作的函数的组合逻辑、存储位的存储单元,以及控制存储器单元更新的时钟信号。

HCL(硬件控制语言)用来描述不同处理器设计的控制逻辑。
返回目录

教材课后习题总结


4.1题:解析已作为介绍Y86-64指令编码的例子给出。

4.2题:考察“字节序列与Y86-64指令之间的转换”。此题关键要根据“代码部分”(即指令编码的前4位)确定其指令编码长度,从而将一个整体的编码划分为不同的指令。

『例如』:A.0x100:30f3fcffffffffffffff40630008000000000000字节序列转换为Y86-64指令为:

0x100: irmovq $-4,%rbx
0x10a: rmmovq %rsi,0x0800(%rbx)

『解析』:通过“30”我们得知第一个指令为irmovq ……,编码长度为10字节,所以可以确定从“40”开始为下一个指令rmmovq ……;再看寄存器指示符字节和数值部分,通过观察“Y86-64寄存器标识符”可以确定“30f3fcffffffffffffff”中的第二字节“f3”表示该指令至用到一个寄存器“%rbx”,后面八字节数字为以小端方式组织的立即数,将“fcffffffffffffff”转换为真值为-4。其他字节序列的转换过程类似,这里不再赘述。

4.3题:有了iaddq指令,我们可以省去P251页Y86-64代码中的第2-3行,直接用iaddq $8,%rdiiaddq $-1,%rsi两条指令替换10-11行。

4.4题&4.5题:此题涉及到我们常用的几种操作:

  • xorq %rax,%rax:用异或来给某个数置零
  • andq %rsi,%rsi: 自身相与来设置条件码,判断一个数是否为0
  • pushq ……popq ……来保护某个寄存器中的值
  • xorq %r11,%r11subq %r10,%r11加上跳转语句jle……来取一个数的绝对值:当前%r11中的值为%r10的值的相反数,如果执行subq %r10,%r11后%r11小于等于0,则说明%r10中的值为正数,绝对值为其本身,如果%r11的值大于0,则说明%r10的值为负,用rrmovq %r11,%r10给%r10取反。

此外,我们还经常用“x∧0”来给一个数置0,用“x∨1”来给一个数置1.

2017-2018-1 20155312 学习《深入理解计算机系统》第四章:处理器体系结构


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
author-avatar
冷瞳流行精品服装店
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有