【计算机系统导论】3.4 指令系统与指令集

好马配好鞍,有了强大的硬件,也需要配套的软件才能真正发挥作用,那么指令系统就是在硬件之上真正留给程序员发挥的地方。


  • 指令执行
  • 指令级并行
  • 机器指令特征(要素、表示、类型、地址数目、指令集设计)
  • 操作数类型(数值、字符、逻辑数据)
  • Intel x86 和 ARM 数据类型
  • 操作类型(数据传送、算术运算、逻辑运算、转换、输入输出、系统控制、控制转移)
  • Intel x86 和 ARM 操作类型
  • 寻址方式(立即寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址、偏移寻址、栈寻址)
  • 指令格式(长度、位的分配、变长指令,VLIW)
  • CISC 与 RISC(对比、争论)
  • 指令周期(间接周期、数据流)
  • 指令流水线技术(流水线策略、性能、冒险、处理分支指令、Intel 80486的流水线)
  • ARM CORTEX-A8(指令取指单元、指令译码单元、整数执行单元、SIMD 和浮点流水线)
  • ARM 指令集(寻址模式、比较和条件分支、ARM 的特色)
  • x86 的指令集(寄存器和数据寻址模式、整数操作、指令编码)
  • 异常(MIPS 体系结构中的处理、流水线中的异常)
  • 控制流
  • 中断和指令周期(中断处理、多个中断)

存储程序计算机的两个准则是指令的使用与数字没有区别,以及使用可修改的存储器。选择机器可以理解的指令集需要精妙地平衡程序执行需要的指令数目、指令指令所需的时钟周期数和时钟的速度。在做精妙平衡时有四条准则可以指导设计者:

  1. 简单源于规整。
  2. 越小越快
  3. 加速常用操作
  4. 优秀的设计需要好的折中

计算机性能水平的提高是永无止境的,计算机设计者和程序员必须理解更广泛的问题。硬件和软件设计者都是用分层的方法构建计算机系统,每个下层都对其上层隐藏本层的细节。这个抽象原理是理解当今计算机系统的基础,但这并不意味着设计者只要懂得抽象原理就足够了。也许最重要的抽象层次是硬件和底层软件之间的接口,称为指令集体系结构。将指令集体系结构作为一个常量可以使其不同的实现方法(价格和性能可能不同)能够运行同一软件。产生的一个副效应:这些预先排除可能需要接口发生变化的那些革新结构。

我们知道处理器必须执行一系列指令,每条指令执行某个简单操作,例如两个数相加。指令被编码为由一个或多个字节序列组成的二进制格式。一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构(Instruction-Set Architecture, ISA)。不同的处理器家族,例如 Intel IA32、IBM/Freescale PowerPC 和 ARM 处理器家族,都有不同的 ISA。一个程序编译成在一种机器上运行,就不能在另一种机器上运行。另外,同一个家族里也有很多不同型号的处理器。虽然每个厂商制造的处理器性能和复杂性不断提高,但是不同的型号在 ISA 级别上都保持着兼容。一些常见的处理器家族(例如 IA32)中的处理器分别又多个厂商提供。因此,ISA 在编译器编写者和处理器设计人员之间提供了一个概念抽象层,编译器编写者只需要知道允许哪些指令,以及它们是如何编码的;而处理器设计者必须建造出执行这些指令的处理器。

一个很重要的概念是,现代处理器的实际工作方式可能跟 ISA 隐含的计算模型大相径庭。ISA 模型看上去应该是顺序指令执行,也就是先取出一条指令,等到它执行完毕,再开始下一条。然而,与一个时刻只执行一条指令相比,通过同时处理多条指令的不同部分,处理器可以获得较高的性能,为了保证处理器能达到同顺序执行相同的结果,人们采用了一些特殊的机制。在计算机科学中,用巧妙的方法在提高性能的同时,又保持一个更简单、更抽象模型的功能,这种想法是众所周知的。在 Web 浏览器或平衡二叉树和哈希表这样的信息检索数据结构中使用缓存,就是这样的例子。

从汇编说起

指令格式与类型

指令设计

指令类型

数据移动、单双操作数、比较与条件转移、过程调用、循环控制

Core i7 架构指令系统(包含指令格式)

龙芯架构指令系统(包含指令格式)

寻址

除了将变量与寄存器对应起来,编译器还在存储器中为诸如数组和结构这样的数据结构分配相应的位置。然而,编译器可以将它们在存储器中的起始地址放到数据传送指令中。

很多程序都用到字节类型,且大多数体系结构按字节编地址。因此,一个字的地址必和它所包括的四个字节中某个的地址相匹配,且连续字的地址相差 4。在 MIPS 中,字的起始地址必须是 4 的倍数,这叫对齐限制,许多体系结构都有这样的限制。

有两种类型的字节寻址的计算机:一种使用最左边或『大端』big end 字节的地址作为字地址;另一种使用最右边或『小端』little end 字节的地址作为字地址。

寻址方式

  • 各类寻址,至少八种
  • 数组分配与寻址
  • 不同数据类型的寻址

Core i7 的寻址

龙芯的寻址

寻址方式讨论

控制流

顺序控制流和转移

过程

中断

系统过程

漏洞

漏洞从大的方面分为四种:DDOS 攻击;信息泄露;权限夺取;权限升格

对软件漏洞的攻击有很多种。对软件开发者的程序错误的攻击,有代表性的有以下 5 种:缓冲区溢出、整数溢出、跨站点脚本攻击(XSS)、SQL 注入、跨站点伪造请求(CSRF)

指令集

最早体系结构的指令集受到当时硬件技术的限制。只要硬件技术允许,计算机架构师就会探索支持高级语言的方式。因为这一探索,在三个不同时期内,人们关于如何高效支持程序有着截然不同的考虑。20 世纪 60 年代,栈体系结构变得非常流行。人们认为它们与高级语言非常匹配,根据当时的编译器技术,可能也确实如此。20 世纪 70 年代,架构师主要关注如何降低软件成本。其解决方案主要是用硬件代替软件,或者提供能够简化软件设计人员任务的高级体系结构。其结果就是高级语言计算机体系结构和诸如 VAX 之类的强大体系结构,这种体系结构有大量的寻址方式、多种数据类型和高度正交的体系结构。20 世纪 80 年代,一些更高级的编译器技术和对处理器性能的再度重视见证了简单体系结构的回归,其主要基础就是载入-存储型计算机。

20 世纪 90 年代,指令集体系结构发生了以下变化

  • 地址大小加倍(32 位到 64 位)
  • 通过条件执行优化条件分支
  • 通过预取优化缓存性能
  • 支持多媒体
  • 浮点运算速度更快

指令集:特征和功能

计算机指令最重要的元素是操作码(opcode),它指明将完成的操作、源和目的操作数的引用方式,并通常隐式指明下一条指令的来源。

操作码指定的操作,一般可有如下类型:算术和逻辑运算,在两个寄存器、寄存器和存储器或存储器两个位置之间传送数据,输入/输出,控制。

操作数引用方式指定如何寻找被操作数据的寄存器或存储器的位置。数据类型可以是地址、数值、字符或逻辑数据。

各类处理器中的一个普遍的体系结构是栈 stack 的使用,栈对程序员是可见的或是不可见的。栈用于管理过程的调用和返回,也可用来提供另一种寻址存储器的方式。栈的基本操作是 PUSH 和 POP,以及在栈顶部一或两个位置上完成的操作。一般来说,栈都实现为从高地址向低地址增长。

字节可以寻址的处理器可分为大端(big endian)、小端(little endian)、双端(bi-endian)这几类。如果多字节的数值是以最高有效字节存于最低地址值的字节来顺序存储,则称为大端;如果它们是以最低有效字节存于最低地址值的字节来顺序存储,则称为小端。既支持大端又支持小端的处理器是双端处理器。

指令集:寻址方式和指令格式

指令的操作数引用有两种形式:一是指令中含有操作数的实际值(立即数),而是指令中含有对操作数地址的引用。各种指令集使用类型广泛的寻址方式。这包括直接寻址(操作数地址在指令的地址字段中)、间接寻址(地址字段指向一个存储位置,此位置含有操作数地址)、寄存器寻址、寄存器间接寻址,以及各种形式的偏移寻址(寄存器值加上地址值产生操作数地址)。

指令格式定义了指令中字段的布局。指令格式设计是一件非常复杂的事情,要考虑到诸多因素,如指令长度是定长还是变长,指派给操作码和每个操作数引用的位数,以及如何确定寻址方式等。

CISC vs RISC

对设计新型处理器体系结构来说,高级语言程序行为的研究具有指导意义,成果之一就是产生了精简指令集计算机(RISC)。程序中赋值语句占最大份额,这暗示着简单的数据传送应当优化。程序中还是许多 IF 和 LOOP 语句,意味着基本的顺序控制机制需要进行优化,以便有效地使用流水技术。操作数引用样式的研究表明,在寄存器中保持适当数量的操作数会有助于性能的提高

这些研究已导出 RISC 机器的关键特征:其一,有限的指令集并具有固定格式;其二,大量的寄存器或利用编译器来优化寄存器的使用;其三,强调对指令流水线的优化。

RISC 的简单指令集便于有效的流水化,因为每条指令只有少数几种操作,并且这些操作是比较容易确定的。RISC 指令集体系结构自身也有助于实施延迟分支(delayed branch) 技术,这种技术将分支指令和其他指令重排从而提高流水线效率。

多媒体指令

https://zh.wikipedia.org/wiki/MMX

MMX SSE

ARM 指令集

寻址模式、比较和条件分支、ARM 的特色

x86 指令集

链接器

基本知识

三种对象文件

对象文件格式

链接过程

符号解析

重定位

打包常用程序

静态库

共享库

动态库

捧个钱场?