backcolor=rgba(255, 255, 255, 0.5)]CPU执行的也不只是一条指令,一般一个程序包含很多条指令

[backcolor=rgba(255, 255, 255, 0.5)]因为有if…else、for这样的条件和循环存在,这些指令也不会一路平直执行下去。

[backcolor=rgba(255, 255, 255, 0.5)]一个计算机程序是怎么被分解成一条条指令来执行的呢

1 CPU如何执行指令

[backcolor=rgba(255, 255, 255, 0.5)]CPU里差不多几百亿个晶体管

[backcolor=rgba(255, 255, 255, 0.5)]实际上,一条条计算机指令执行起来非常复杂

[backcolor=rgba(255, 255, 255, 0.5)]好在CPU在软件层面已经为我们做好了封装

[backcolor=rgba(255, 255, 255, 0.5)]对于程序员来说,我们只要知道,写好的代码变成了指令之后,是一条一条顺序执行

[backcolor=rgba(255, 255, 255, 0.5)]不管几百亿的晶体管的背后是怎么通过电路运转起来的

[backcolor=rgba(255, 255, 255, 0.5)]逻辑上,我们可以认为,CPU其实就是由一堆寄存器组成的

[backcolor=rgba(255, 255, 255, 0.5)]而寄存器就是CPU内部,由多个触发器(Flip-Flop)或者锁存器(Latches)组成的简单电路。

触发器和锁存器,其实就是两种不同原理的数字电路组成的逻辑门
如果想要深入学习的话,可以学习数字电路的相关课程

[backcolor=rgba(255, 255, 255, 0.5)]N个触发器或者锁存器,就可以组成一个N位(Bit)的寄存器,能够保存N位的数据

[backcolor=rgba(255, 255, 255, 0.5)]比方说,我们用的64位Intel服务器,寄存器就是64位的

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]CPU里有很多种不同功能的

1.1 寄存器

[backcolor=rgba(255, 255, 255, 0.5)]寄存器(Register),是中央处理器内的其中组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器。在中央处理器的算术及逻辑部件中,包含的寄存器有累加器。

[backcolor=rgba(255, 255, 255, 0.5)]在计算机体系结构里,处理器中的寄存器是少量且速度快的计算机存储器,借由提供快速共同地访问数值来加速计算机程序的运行:典型地说就是在已知时间点所作的之计算中间的数值。

[backcolor=rgba(255, 255, 255, 0.5)]寄存器是存储器层次结构中的最顶端,也是系统操作数据的最快速途径。寄存器通常都是以他们可以保存的比特数量来估量,举例来说,一个8位寄存器或32位寄存器。寄存器现在都以寄存器数组的方式来实现,但是他们也可能使用单独的触发器、高速的核心存储器、薄膜存储器以及在数种机器上的其他方式来实现出来。

[backcolor=rgba(255, 255, 255, 0.5)]这个名词通常都用来意指由一个指令之输出或输入可以直接索引到的寄存器组群。更适当的是称他们为“架构寄存器”。例如,x86指令集定义八个32位寄存器的集合,但一个实现x86指令集的CPU可以包含比八个更多的寄存器。

1.1.1 PC寄存器(Program Counter Register)

[backcolor=rgba(255, 255, 255, 0.5)]亦称指令地址寄存器(Instruction Address Register)

[backcolor=rgba(255, 255, 255, 0.5)]存放下一条需要执行的计算机指令的内存地址

1.1.2 指令寄存器(Instruction Register)

[backcolor=rgba(255, 255, 255, 0.5)]存放当前正在执行的指令

1.1.3 条件码寄存器(Status Register)

[backcolor=rgba(255, 255, 255, 0.5)]用里面的一个一个标记位(Flag),存放CPU进行算术或者逻辑计算的结果

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]CPU里面还有更多用来存储数据和内存地址的寄存器

[backcolor=rgba(255, 255, 255, 0.5)]这样的寄存器通常一类里面不止一个

[backcolor=rgba(255, 255, 255, 0.5)]通常根据存放的数据内容来给它们取名字,比如

  • 常量寄存器
    用来持有只读的数值(例如0、1、圆周率等等)。由于“其中的值不可更改”这一特殊性质,这些寄存器未必会有实体的硬件电路相对应,例如将从零常数寄存器读的操作实现为接通目标寄存器的下拉电阻。
    一般而言,即使真正在硬件中放置常数寄存器也未必会是出于体系结构理论上的考虑,而很可能是由硬件描述语言为了简化操作而自动生成的电路
  • 整数寄存器
    用来存储整数数字(参考以下的浮点寄存器)。在某些简单(或旧)的CPU,特别的数据寄存器是累加器,作为数学计算之用。
  • 浮点数寄存器(FPRs)
    用来存储浮点数字。
  • 向量寄存器
    用来存储由向量处理器运行SIMD指令所得到的数据。
  • 地址寄存器
    持有存储器地址,以及用来访问存储器。在某些简单/旧的CPU里,特别的地址寄存器是索引寄存器(可能出现一个或多个)。

[backcolor=rgba(255, 255, 255, 0.5)]有些寄存器既可以存放数据,又能存放地址,我们就叫它通用寄存器(GPRs)。

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]程序执行的时候,CPU会

  • 根据PC寄存器里的地址
  • 从内存里面把需要执行的指令读取到指令寄存器里面执行
  • 然后根据指令长度自增
  • 开始顺序读取下一条指令

[backcolor=rgba(255, 255, 255, 0.5)]可以看到,一个程序的一条条指令,在内存里是连续保存的,也会一条条顺序加载

[backcolor=rgba(255, 255, 255, 0.5)]而有些特殊指令,比如上一讲我们讲到J类指令,也就是跳转指令,会修改PC寄存器里面的地址值

[backcolor=rgba(255, 255, 255, 0.5)]这样,下一条要执行的指令就不是从内存里面顺序加载的了

[backcolor=rgba(255, 255, 255, 0.5)]事实上,这些跳转指令的存在,也是我们可以在写程序的时候,使用

  • if…else条件语句
  • while/for循环语句

[backcolor=rgba(255, 255, 255, 0.5)]的原因

2 从if/else看程序的执行和跳转

[backcolor=rgba(255, 255, 255, 0.5)]我们现在就来看一个包含if…else的简单程序。

  • test.c

[backcolor=rgba(255, 255, 255, 0.5)]用rand生成了一个随机数r(0/1)

  • 当r是0,我们把之前定义的变量a设成1
  • 不然就设成2

[backcolor=rgba(255, 255, 255, 0.5)]我们把这个程序编译成汇编代码。你可以忽略前后无关的代码,只关注于这里的if…else条件判断语句

  • 对应的汇编代码是这样的

[backcolor=rgba(255, 255, 255, 0.5)]对于r == 0的条件判断,被编译成了cmp和jne两条指令。

  • cmp指令比较了前后两个操作数的值
    DWORD PTR 代表操作的数据类型是32位的整数
    rbp-0x4则是一个寄存器的地址
    第一个操作数就是从寄存器里拿到的变量r的值
    第二个操作数0x0就是我们设定的常量0的16进制表示

[backcolor=rgba(255, 255, 255, 0.5)]cmp指令的比较结果,会存入到条件码寄存器

状态寄存器又名条件码寄存器,它是计算机系统的核心部件——运算器的一部分
状态寄存器用来存放两类信息:
一类是体现当前指令执行结果的各种状态信息(条件码),如有无进位(CF位)、有无溢出(OF位)、结果正负(SF位)、结果是否为零(ZF位)、奇偶标志位(P位)等
另一类是存放控制信息(PSW:程序状态字寄存器),如允许中断(IF位)、跟踪标志(TF位)等
有些机器中将PSW称为标志寄存器FR(Flag Register)。

[backcolor=rgba(255, 255, 255, 0.5)]如果比较结果 True,即 r == 0,就把零标志条件码(对应的条件码是ZF,Zero Flag)设置为1

条件码是CPU根据运算结果由硬件设置的位,体现当前指令执行结果的各种状态信息
例如:算术运算产生的正、负、零或溢出等的结果。条件码可被测试,作为分支运算的依据,此外,有些条件码可被设置,例如对于最高位进位标志C,可用指令对它置位和复位。

[backcolor=rgba(255, 255, 255, 0.5)]Intel的CPU下还有

  • 进位标志(CF,Carry Flag)
    最近的操作使最高位产生了进位。可以用来检查无符号操作数据的溢出。
  • 符号标志(SF,Sign Flag)
    最近的操作得到的结果为负数。
  • 溢出标志(OF,Overflow Flag)
    最近的操作导致一个补码溢出--正溢出或负溢出

[backcolor=rgba(255, 255, 255, 0.5)]用在不同的判断条件下。

[backcolor=rgba(255, 255, 255, 0.5)]cmp指令执行完成之后,PC寄存器会自增,开始执行下一条jne的指令

[backcolor=rgba(255, 255, 255, 0.5)]跟着的jne指令(jump if not equal),它会查看对应的零标志位

[backcolor=rgba(255, 255, 255, 0.5)]如果为0,会跳转到后面跟着的操作数4a的位置

[backcolor=rgba(255, 255, 255, 0.5)]4a,对应汇编代码的行号,也就是else条件里的第一条指令

[backcolor=rgba(255, 255, 255, 0.5)]当跳转发生,PC寄存器不再是自增变成下一条指令的地址,而被直接设置4a这个地址

[backcolor=rgba(255, 255, 255, 0.5)]这个时候,CPU再把4a地址里的指令加载到指令寄存器执行。

[backcolor=rgba(255, 255, 255, 0.5)]跳转到执行地址为4a的指令,实际是一条mov指令

[backcolor=rgba(255, 255, 255, 0.5)]第一个操作数和前面的cmp指令一样,是另一个32位整型的寄存器地址,以及对应的2的16进制值0x2

[backcolor=rgba(255, 255, 255, 0.5)]mov指令把2设置到对应的寄存器里去,相当于一个赋值操作

[backcolor=rgba(255, 255, 255, 0.5)]然后,PC寄存器里的值继续自增,执行下一条mov指令。

[backcolor=rgba(255, 255, 255, 0.5)]这条mov指令的第一个操作数eax,代表累加寄存器

在中央处理器中,累加器 (accumulator) 是一种寄存器,用来储存计算产生的中间结果。如果没有像累加器这样的寄存器,那么在每次计算 (加法,乘法,移位等等) 后就必须要把结果写回到 内存,也许马上就得读回来。然而存取主存的速度是比从算术逻辑单元到有直接路径的累加器存取更慢。

[backcolor=rgba(255, 255, 255, 0.5)]第二个操作数0x0则是16进制的0的表示。这条指令其实没有实际的作用,它的作用是一个占位符

[backcolor=rgba(255, 255, 255, 0.5)]if条件如果满足,在赋值的mov指令执行完成之后,有一个jmp的无条件跳转指令

[backcolor=rgba(255, 255, 255, 0.5)]跳转的地址就是这一行的地址51

[backcolor=rgba(255, 255, 255, 0.5)]我们的main函数没有设定返回值,而mov eax, 0x0 其实就是给main函数生成了一个默认的为0的返回值到累加器里面

[backcolor=rgba(255, 255, 255, 0.5)]if条件里面的内容执行完成之后也会跳转到这里,和else里的内容结束之后的位置是一样的。

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]上一讲我们讲打孔卡的时候说到,读取打孔卡的机器会顺序地一段一段地读取指令,然后执行。

[backcolor=rgba(255, 255, 255, 0.5)]执行完一条指令,它会自动地顺序读取下一条指令

[backcolor=rgba(255, 255, 255, 0.5)]如果执行的当前指令带有跳转的地址,比如往后跳10个指令,那么机器会自动将卡片带往后移动10个指令的位置,再来执行指令

[backcolor=rgba(255, 255, 255, 0.5)]同样的,机器也能向前移动,去读取之前已经执行过的指令

[backcolor=rgba(255, 255, 255, 0.5)]这也就是我们的while/for循环实现的原理。

[backcolor=rgba(255, 255, 255, 0.5)]如何通过if…else和goto来实现循环?

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]我们再看一段简单的利用for循环的程序。我们循环自增变量i三次,三次之后,i>=3,就会跳出循环。整个程序,对应的Intel汇编代码就是这样的:

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]可以看到,对应的循环也是用1e这个地址上的cmp比较指令

[backcolor=rgba(255, 255, 255, 0.5)]和紧接着的jle条件跳转指令来实现的

[backcolor=rgba(255, 255, 255, 0.5)]主要的差别在于,这里的jle跳转的地址,在这条指令之前的地址14,而非if…else编译出来的跳转指令之后

[backcolor=rgba(255, 255, 255, 0.5)]往前跳转使得条件满足的时候,PC寄存器会把指令地址设置到之前执行过的指令位置,重新执行之前执行过的指令,直到条件不满足,顺序往下执行jle之后的指令,整个循环才结束。

[backcolor=rgba(255, 255, 255, 0.5)]

[backcolor=rgba(255, 255, 255, 0.5)]如果你看一长条打孔卡的话,就会看到卡片往后移动一段,执行了之后,又反向移动,去重新执行前面的指令。

[backcolor=rgba(255, 255, 255, 0.5)]jle和jmp指令,有点像程序语言里面的goto命令,直接指定了一个特定条件下的跳转位置

[backcolor=rgba(255, 255, 255, 0.5)]虽然我们在用高级语言开发程序的时候反对使用goto,但是实际在机器指令层面,无论是if…else…也好,还是for/while也好,都是用和goto相同的跳转到特定指令位置的方式来实现的。

3 总结

[backcolor=rgba(255, 255, 255, 0.5)]学习了程序里的多条指令,究竟是怎么样一条一条被执行的

[backcolor=rgba(255, 255, 255, 0.5)]除了简单地通过PC寄存器自增的方式顺序执行外

[backcolor=rgba(255, 255, 255, 0.5)]条件码寄存器会记录下当前执行指令的条件判断状态

[backcolor=rgba(255, 255, 255, 0.5)]然后通过跳转指令读取对应的条件码

[backcolor=rgba(255, 255, 255, 0.5)]修改PC寄存器内的下一条指令的地址

[backcolor=rgba(255, 255, 255, 0.5)]最终实现if…else以及for/while这样的程序控制流程。

[backcolor=rgba(255, 255, 255, 0.5)]虽然我们可以用高级语言,可以用不同的语法,比如 if…else 这样的条件分支,或者 while/for 这样的循环方式,来实现不用的程序运行流程

[backcolor=rgba(255, 255, 255, 0.5)]但是回归到计算机可以识别的机器指令级别,其实都只是一个简单的地址跳转而已,也就是一个类似于goto的语句。

[backcolor=rgba(255, 255, 255, 0.5)]想要在硬件层面实现这个goto语句,除了本身需要用来保存下一条指令地址,以及当前正要执行指令的PC寄存器、指令寄存器外

[backcolor=rgba(255, 255, 255, 0.5)]我们只需要再增加一个条件码寄存器,来保留条件判断的状态。这样简简单单的三个寄存器,就可以实现条件判断和循环重复执行代码的功能。

4 推荐阅读

  • 《深入理解计算机系统》的第3章
    详细讲解了C语言和Intel CPU的汇编语言以及指令的对应关系,以及Intel CPU的各种寄存器和指令集。

[backcolor=rgba(255, 255, 255, 0.5)]Intel指令集相对于之前的MIPS指令集要复杂一些

  • 所有的指令是变长的
    从1个字节到15个字节不等
  • 即使是汇编代码,还有很多针对操作数据的长度不同有不同的后缀
  • 更多技术资讯可关注:gzitcast

计算机组成原理- 旋转跳跃的指令实现相关推荐

  1. 计算机组成流水系统可以,计算机组成原理实验十三建立指令流水系统实验

    计算机组成原理实验十三建立指令流水系统实验 评阅计算机组成原理实验报告十三姓名 学号 时间 四7-9 地点 行健楼 606机房 一 建立指令流水系统实验 1. 实验内容及要求(1)实验内容:1. 分析 ...

  2. 计算机组成原理——机器字长、指令字长、存储字长

    计算机组成原理--机器字长.指令字长.存储字长 字长: 字长: 一个字中的二进制位的位数,是计算机系统结构中的一个重要特性.字长在计算机结构和操作的多个方面均有体现.计算机中大多数寄存器的大小是一个字 ...

  3. 计算机组成原理实验扩展RCL指令,计算机组成原理实验五扩展指令设计.doc

    计算机组成原理实验五扩展指令设计 实验五 扩展指令设计 实验目的 1. 进一步掌握计算机组合逻辑控制器的功能.组成知识. 2. 进一步学习计算机各类典型指令的执行流程. 3. 学习组合逻辑控制器的设计 ...

  4. 计算机组成原理实验所用的指令,计算机组成原理实验报告-控制器及微指令系统的操作与运用...

    计算机组成原理实验报告-控制器及微指令系统的操作与运用 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 成绩:实 验 报 告课程名称 ...

  5. 【计算机组成原理】流水线式指令执行

    文章目录 前言 一.处理器的构成 二.数据通路 1. 流水线工作 2. 冒险 3. 流水线寄存器 三.FPGA相比于CPU的速度优势 总结 前言 最近在阅读<计算机组成与设计 硬件/软件接口(原 ...

  6. 计算机组成原理中的MPY指令,8位算术逻辑运算

    8位算术逻辑运算Tag内容描述: 1.计算机组成原理实验,1/25,一.实验目的,三.实验原理,四.实验连线,五.实验步骤,实验一8位算术逻辑运算实验,二.实验设备,2/25,一.实验目的,掌握算术逻 ...

  7. 计算机组成原理-原理篇:指令与运算-13加法器:如何像搭乐高一样搭电路(上)?

    1. 异或门和半加器 面这些门电路的标识,你需要非常熟悉,后续的电路都是由这些门电路组合起来的. 这些基本的门电路,是我们计算机硬件端的最基本的"积木",就好像乐高积木里面最简单的 ...

  8. 计算机组成原理两数相加指令,计算机组成原理复习题

    27. 一个16K×32位的存储器,其地址线和数据线的总和是 . A.48 B.46 C.36 答案:B 28.由于磁盘上的内部同心圆小于外部同心圆,则对其所存储的数据量而言, . A.内部同心圆大于 ...

  9. 【计算机组成原理】程序,指令,机器指令,微程序,微指令,微命令,微操作的关系

    程序: 程序由一些指令组成 指令: 这里的指令指 MOV AX,BX这样的汇编指令 机器指令: 机器指令是指令翻译后的结果,比如上面的指令翻译结果为89D8 微指令: 机器指令是由数个微指令组成,且每 ...

  10. 【CO101】计算机组成原理笔记2 —— MIPS指令转机器码

    笔者:YY同学 生命不息,代码不止.好玩的项目尽在GitHub 文章目录 RISC 与 CISC MIPS 指令类型 R Type(Register) I Type(Immediate) M Type ...

最新文章

  1. ***基础课----***踩点
  2. 计算机机房电力切换演练方案,机房停电应急演练实施具体技术方案.doc
  3. ZOJ2930 The Worst Schedule(最小割)
  4. windows拷贝内容到ubuntu中
  5. 小程序开发 宽度100%_这是您作为开发人员可以实现100%年度目标的方式
  6. [NOI2014]魔法森林
  7. 字节流通向字符流的桥梁:InputStreamReader
  8. Accurate, Large Minibatch SGD
  9. AutoCAD DWG格式文件去除教育版戳记方法
  10. Python中的多线程是假的多线程?
  11. 小米盒子打开adb调试模式
  12. 人工智能 之 定义与发展
  13. 移动开发视频资源百度网盘地址分享
  14. 2021-09-03 【N02】小程序开发学习笔记
  15. 初中使用计算机,初中生使用计算器的利和弊!!!急!!!!!!!!!!!!!!!!!!!!
  16. smzdm 扫地机器人_2020年双十二有什么值得购买的扫地机器人,科沃斯T8、米家1T、石头T7,还有什么推荐的品牌吗?...
  17. MySQL入门——索引
  18. 办公室局域网打印机配置笔记及0x0000011b连接错误成功解决方法
  19. jQuery实现对file对象的压缩
  20. 《AutoCAD 2014中文版实用教程》一一1.2 标题栏

热门文章

  1. jxt解析上传的xls文件
  2. 灵感爆发:An/flash 影片剪辑动画播放一遍后,摆脱paly()的控制
  3. 流程控制语句 函数 对象和数组
  4. 顺丰同城快递预下单接口
  5. 如何面试大厂web前端?(沟通软技能总结)
  6. 【编译原理】 CS143 斯坦福大学公开课 第一周:简介
  7. djyvp计算机电缆参数,DJYVP计算机电缆2x2x1.5型号规格含义
  8. 揭秘跨境电商亚马逊店铺新手培训骗局!有人已经被骗了好几万了!
  9. IP地址分类(A类 B类 C类 D类 E类)
  10. 带宽和下载速度的关系