文章目录
计算机组成原理
1 计算机系统概述
1.1 计算机发展历程
1.1.1 计算机硬件的发展
-
计算机的四代变化
-
第一代计算机(1946一1957年)电子管时代
特点:逻辑元件采用电子管:使用机器语言进行编程;主存用延迟线或磁鼓存储信息,容量极小;体积庞大,成本高;运算速度较低,一般只有几千次到几万次每秒。
-
第二代计算机(1958一1964年)晶体管时代
特点:逻辑元件采用晶体管;运算速度提高到几万次到几十万次每秒;主存使用磁芯存储器;计算机软件也得到了发展,开始出现了高级语言及其编译程序,有了操作系统的雏形。
-
第三代计算机(1965一1971年)中小规模集成电路时代
特点:逻辑元件采用中小规模集成电路;半导体存储器开始取代磁芯存储器;高级语言发展迅速,操作系统也进一步发展,开始有了分时操作系统。
-
第四代计算机(1972年至今)超大规模集成电路时代
特点:逻辑元件采用大规模集成电路和超大规模集成电路,产生了微处理器;诸如并行、流水线、高速缓存和虚拟存储器等概念用在了这代计算机中。
-
-
计算机元件的更新换代
- 摩尔定律。当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍。
- 半导体存储器的发展。1970年,仙童半导体公司生产出第一个较大容量的半导体存储器,至今,半导体存储器经历了11代:单芯片1KB、4KB、16KB、64KB、256KB、1MB、4MB、16MB、64MB、256MB和现在的1GB。
- 微处理器的发展。自1971年Intel公司开发出第一个微处理器Intel 4004至今,微处理器经历了Intel 8008(8位)、Intel 8086(16位)、Intel 80386(32位)、Pentium(32位)、Pentium III(64位)、Pentium 4(64位)、Core i7(64位)等。这里的32位、64位指的是机器字长,是指计算机进行一次整数运算所能处理的二进制数据的位数。
1.1.2 计算机软件的发展
-
机器语言的发展
机器语言→汇编语言→FORTRAN→PASCAL→C++→Java
-
操作系统的发展
Windows、UNIX、Linux
1.2 计算机系统层次结构
1.2.1 计算机系统的组成
计算机系统=硬件+软件
硬件:计算机的实体,如主机、外设等;软件:由具有各类特殊功能的程序组成。
1.2.2 计算机硬件
-
冯·诺依曼机基本思想
冯·诺依曼在研究EDVAC机时提出了“存储程序”的概念,“存储程序”的思想奠定了现代计算机的基本结构,以此概念为基础的各类计算机通称为冯·诺依曼机,其特点如下:
- 1)采用“存储程序”的工作方式。
- 2)计算机硬件系统由运算器、存储器、控制器、输入设备和输出设备5大部件组成。
- 3)指令和数据以同等地位存储在存储器中,形式上没有区别,但计算机应能区分它们。
- 4)指令和数据均用二进制代码表示。指令由操作码和地址码组成,操作码指出操作的类型,地址码指出操作数的地址。
早期冯诺依曼机以运算器为中心,I/O通过运算器和存储器传送数据,以控制流驱动方式。
存储程序思想:将指令以二进制代码的形式事先输入计算机的主存储器,然后按其在存储器中的首地址执行程序的第一条指令,以后就按该程序的规定顺序执行其他指令,直至程序执行结束。
-
现代计算机的机构
现代计算机以存储器为中心,CPU=运算器+控制器。
-
计算机的功能部件
-
输入设备
任务:将程序和数据以机器所能识别和接受的信息形式输入计算机。
如键盘,此外还有鼠标、扫描仪、摄像机等。
-
输出设备
任务:将计算机处理的结果以人们所能接受的形式或其他系统所要求的信息形式输出。
如显示器、打印机。
输入输出设备(简称I/O设备)是计算机与外界联系的桥梁,是计算机中不可缺少的重要组成部分。
-
存储器
存储器分为主存储器(又称内存储器)和辅助存储器(又称外存储器)。
CPU能够直接访问的存储器是主存储器。辅助存储器用于帮助主存储器记忆更多的信息,辅助存储器中的信息必须调入主存后,才能为CPU所访问。
主存储器的工作方式是按存储单元的地址进行存取,这种存取方式称为按地址存取方式。
-
存储体:存放二进制信息。
存储体由许多存储单元组成,每个存储单元包含若干存储元件,每个存储元件存储一位二进制代码“0”或“1”。
因此存储单元可存储一串二进制代码,称这串代码为存储字,称这串代码的位数为存储字长,存储字长可以是1B(8bit)或是字节的偶数倍。
-
地址寄存器(MAR):存放访存地址,经过地址译码后找到所选的存储单元。
MAR用于寻址,其位数对应着存储单元的个数,如MAR为10位,则有210=1024个存储单元,记为1K。MAR的长度=PC的长度。
-
数据寄存器(MDR):用于暂存要从存储器中读或写的信息,时序控制逻辑用于产生存储器操作所需的各种时序信号。
MDR的位数=存储字长,一般为字节的2次幂的整数倍。
注意:MAR与MDR虽然是存储器的一部分,但在现代计算机中却是存在于CPU中的:另外,后文提到的高速缓存(Cache).也存在于CPU中。
-
-
运算器
运算器是计算机的执行部件,用于进行算术运算和逻辑运算。
运算器的核心是算术逻辑单元(Arithmetic and Logical Unit,ALU)。
运算器包含若干通用寄存器,用于暂存操作数和中间结果,如累加器(ACC)、乘商寄存器(MQ)、操作数寄存器(X)、变址寄存器(X)、基址寄存器(BR)等,其中前3个寄存器是必须具备的。
运算器内还有程序状态寄存器(PSW),也称标志寄存器,用于存放ALU运算得到的一些标志信息或处理机的状态信息,如结果是否溢出、有无产生进位或借位、结果是否为负等。
-
控制器
控制器是计算机的指挥中心,由其“指挥”各部件自动协调地进行工作。
控制器由程序计数器(PC)、指令寄存器(IR)和控制单元(CU)组成。
- PC用来存放当前欲执行指令的地址,具体自动加1的功能(这里的“1”指一条指令的长度),即可自动形成下一条指令的地址,它与主存的MAR之间有一条直接通路。
- IR用来存放当前的指令,其内容来自主存的MDR。指令中的操作码OP(IR)送至CU,用以分析指令并发出各种微操作命令序列:而地址码Ad(IR)送往MAR,用以取操作数。
一般将运算器和控制器集成到同一个芯片上,称为中央处理器(CPU)。CPU和主存储器共 同构成主机,而除主机外的其他硬件装置(外存、I/O设备等)统称为外部设备,简称外设。
-
1.2.3 计算机软件
-
系统软件和应用软件
-
系统软件:一组保证计算机系统高效、正确运行的基础软件,通常作为系统资源提供给用户使用。
如操作系统(OS)、数据库管理系统(DBMS)、语言处理程序、分布式软件系统、网络软件系统、标准库程序、服务性程序等。
-
应用软件:指用户为解决某个应用领域中的各类问题而编制的程序。
如各种科学计算类程序、工程设计类程序、数据统计与处理程序等。
-
-
三个级别的语言
-
机器语言:又称二进制代码语言,需要编程人员记忆每条指令的二进制编码。
机器语言是计算机唯一可以直接识别和执行的语言。
-
汇编语言:汇编语言用英文单词或其缩写代替二进制的指令代码,更容易为人们记忆和理解。
使用汇编语言编辑的程序,必须经过一个称为汇编程序的系统软件的翻译,将其转换为机器语言程序后,才能在计算机的硬件系统上执行。
-
高级语言:高级语言(如C、C++、Java等)是为方便程序设计人员写出解决问题的处理方案和解题过程的程序。
通常高级语言需要经过编译程序编译成汇编语言程序,然后经过汇编操作得到机器语言程序,或直接由高级语言程序翻译成机器语言程序。
计算机无法直接理解和执行高级语言程序,需要将高级语言程序转换为机器语言程序,通常把进行这种转换的软件系统称为翻译程序。翻译程序有以下三类:
- 汇编程序(汇编器):将汇编语言程序翻译成机器语言程序。
- 解释程序(解释器):将源程序中的语句按执行顺序逐条翻译成机器指令并立即执行。
- 编译程序(编译器):将高级语言程序翻译成汇编语言或机器语言程序。
-
-
软件和硬件的逻辑功能等价性
硬件实现的往往是最基本的算术和逻辑运算功能,而其他功能大多通过软件的扩充得以实现。
软、硬件逻辑功能的等价性:对某一功能来说,既可以由硬件实现,又可以由软件实现,从用户的角度来看,它们在功能上是等价的。
软件和硬件逻辑功能的等价性是计算机系统设计的重要依据,软件和硬件的功能分配及其界面的确定是计算机系统结构研究的重要内容。
1.2.4 计算机系统的层次结构
由于软/硬件的设计者和使用者从不同的角度、用不同的语言来对待同一个计算机系统,因此他们看到的计算机系统的属性对计算机系统提出的要求也就各不相同。
下层是上层的基础,上层是下层的扩展。
-
M4:高级语言机器(执行高级语言)它是面向用户的,是为方便用户编写应用程序而设置的。该层由各种高级语言编译程序支持和执行。
在高级语言层之上,还可以有应用程序层,它由解决实际问题的处理程序组成,如文字处理软件、多媒体处理软件和办公自动软件等。
-
M3:汇编语言机器(执行汇编语言):它为用户提供一种符号化的语言,借此可编写汇编语言源程序。这一层由汇编程序支持和执行。
-
M2:操作系统机器(向上提供广义指令):它由操作系统程序实现。
操作系统程序是由机器指令和广义指令组成的,这些广义指令是为了扩展机器功能而设置的,是由操作系统定义和解释的软件指令,所以这一层也称混合层。
-
M1:传统机器(执行机器语言指令):它也是一个实际的机器层,由微程序解释机器指令系统。
-
M0:微程序机器(执行微指令):这是一个实在的硬件层,它由机器硬件直接执行微指令。
没有配备软件的纯硬件系统称为裸机。
M2~M4层称为虚拟机,简单来说就是软件实现的机器。虚拟机器只对该层的观察者存在,对于某层的观察者来说,只能通过该层的语言来了解和使用计算机,而不必关心下层是如何工作的。
软件和硬件之间的界面就是指令集体系结构(ISA),ISA定义了一台计算机可以执行的所有指令的集合,每条指令规定了计算机执行什么操作,以及所处理的操作数存放的地址空间和操作数类型。可以看出,ISA是指软件能感知到的部分,也称软件可见部分。
1.2.5 计算机系统的工作原理
-
“存储程序”工作方式
一个程序的执行就是周而复始地执行一条一条指令的过程。每条指令的执行过程包括:从主存取指令、对指令进行译码、计算下条指令地址、取操作数并执行、将结果送回存储器。
-
程序执行前,先将程序第一条指令的地址存放到PC中
-
取指令时,将PC的内容作为地址访问主存
-
在每条指令执行过程中,都需要计算下条将执行指令的地址,并送至PC
- 若当前指令为顺序型指令,则下条指令地址为PC的内容加上当前指令的长度
- 若当前指令为转跳型指令,则下条指令地址为指令中指定的目标地址
-
当前指令执行完后,根据PC的值到主存中取出的是下条将要执行的指令
-
-
从源程序到可执行文件
在计算机中编写的C语言程序,都必须被转换为一系列的低级机器指令,这些指令按照一种称为可执行目标文件的格式打好包,并以二进制磁盘文件的形式存放起来。
-
预处理阶段:**预处理器(cpp)**对源程序中以字符#开头的命令进行处理,例如将#include命令后面的.h文件内容插入程序文件。输出结果是一个以 .i 为扩展名的源文件hello.i。
-
编译阶段:编译器(ccl)对预处理后的源程序进行编译,生成一个汇编语言源程序hello.s。
汇编语言源程序中的每条语句都以一种文本格式描述了一条低级机器语言指令。
-
汇编阶段:汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一个称为可重定位目标文件的hello.o,它是一种二进制文件,因此用文本编辑器打开会显示乱码。
-
链接阶段:链接器(ld)将多个可重定位目标文件和标准库函数合并为一个可执行目标文件,或简称可执行文件。本例中,链接器将hello.o和标准库函数printf所在的可重定位目标模块printf.o合并,生成可执行文件hello。最终生成的可执行文件被保存在磁盘上。
-
-
程序执行过程的描述
在shell命令下,打印如下字段,解释程序的运行。
unix>./hello hello,world! unix>
- ①shell程序将用户从键盘输入的每个字符逐一读入CPU寄存器
- ②将字符保存到主存储器中,在主存的缓冲区形成字符串“./hello”
- ③接收到Enter键时,shell调出操作系统的内核程序,由内核来加载磁盘上的可执行文件hello到主存中
- ④内核加载完可执行文件中的代码和数据(这里是字符串“hello,world!\n”)后,将hello的第一条指令的地址送至PC,CPU随后开始执行hello程序,它将已加载到主存的字符串“hello,world!\n”中的每个字符从主存取到CPU的寄存器中
- ⑤执行程序,将CPU寄存器中的字符送到显示器。
由此可见,程序的执行过程就是数据在CPU、主存储器和I/O设备之间流动的过程,所有数据的流动都是通过总线、I/O接口等进行的。
-
指令执行过程的描述
可执行文件代码段是由一条一条机器指令构成的,指令是用0和1表示的一串0/1序列,用来指示CPU完成一个特定的原子操作。下图为冯·诺依曼结构的简单模型机。
下面以取数指令(送至运算器的ACC中)为例来说明,其信息流程如下:
-
1)取指令: P C → M A R → M → M D R → I R PC→MAR→M→MDR→IR PC→MAR→M→MDR→IR
根据PC取指令到IR。将PC的内容送MAR,MAR中的内容直接送地址线,同时控制器将读信号送读/写信号线,主存根据地址线上的地址和读信号,从指定存储单元读出指令,送到数据线上,MDR从数据线接收指令信息,并传送到R中。
-
2)分析指令: O P ( I R ) → C U OP(IR)→CU OP(IR)→CU
指令译码并送出控制信号。控制器根据IR中指令的操作码,生成相应的控制信号,送到不同的执行部件。在本例中,IR中是取数指令,因此读控制信号被送到总线的控制线上。
-
3)执行指令: A d ( I R ) → M A R → M → M D R → A C C Ad(IR)→MAR→M→MDR→ACC Ad(IR)→MAR→M→MDR→ACC
取数操作。将IR中指令的地址码送MAR,MAR中的内容送地址线,同时控制器将读信号送读/写信号线,从主存中读出操作数,并通过数据线送至MDR,再传送到ACC中。
每取完一条指令,还须为取下条指令做准备,计算下条指令的地址,即 ( P C ) + 1 → P C (PC)+1→PC (PC)+1→PC。
-
1.3 计算机的性能指标
1.3.1 计算机的主要性能指标
-
字长
字长又指机器字长,是指计算机进行一次整数运算(即定点整数运算)所能处理的二进制数据的位数,通常与CPU的寄存器位数、加法器有关。
指令字长:一个指令中包含的二进制代码的位数
存储字长:一个存储单元存储的二进制代码的长度
-
数据通路带宽
数据通路带宽是指数据总线一次所能并行传送信息的位数。
这里所说的数据通路宽度是指外部数据总线的宽度,它与CPU内部的数据总线宽度(内部寄存器的大小)有可能不同。
-
主存容量
主存容量是指主存储器所能存储信息的最大容量,通常以字节来衡量,也可用字数×字长(如 512K×16位)来表示存储容量。其中,MAR的位数反映了存储单元的个数,MDR的位数反映了存储单元的字长。
例如,MAR为16位,表示216=65536,即此存储体内有65536个存储单元(可称为64K内存,1K=1024),若MDR为32位,表示存储容量为64K×32位。
-
运算速度
-
吞吐量和响应时间
-
吞吐量。指系统在单位时间内处理请求的数量。
它取决于信息能多快地输入内存,CPU能多快地取指令,数据能多快地从内存取出或存入,以及所得结果能多快地从内存送给一台外部设备。几乎每步都关系到主存,因此系统吞吐量主要取决于主存的存取周期。
-
响应时间。指从用户向计算机发送一个请求,到系统对该请求做出响应并获得所需结果的等待时间。
通常包括CPU时间(运行一个程序所花费的时间)与等待时间(用于磁盘访问、存储器访问、I/O操作、操作系统开销等的时间)。
-
-
主频和CPU时钟周期
- CPU时钟周期。通常为节拍脉冲或T周期,即主频的倒数,它是CPU中最小的时间单位,执行指令的每个动作至少需要1个时钟周期。
- 主频(CPU时钟频率)。机器内部主时钟的频率,是衡量机器速度的重要参数。对于同个型号的计算机,其主频越高,完成指令的一个执行步骤所用的时间越短,执行指令的速度越快。例如,常用CPU的主频有1.8GHz、2.4GHz、2.8GHz等。
CPU时钟周期=1/主频,主频通常以Hz(赫兹)为单位,1Hz表示每秒1次。
-
CPI(Cycle Per Instruction),即执行一条指令所需的时钟周期数。
不同指令的时钟周期数可能不同,因此对于一个程序或一台机器来说,其CPI指该程序或该机器指令集中的所有指令执行所需的平均时钟周期数,此时CPI是一个平均值。
-
CPU执行时间,指运行一个程序所花费的时间。
C P U 执行时间 = C P U 时钟周期数 / 主频 = (指令条数 × C P I ) / 主频 CPU执行时间=CPU时钟周期数/主频=(指令条数×CPI)/主频 CPU执行时间=CPU时钟周期数/主频=(指令条数×CPI)/主频
CPU的性能(CPU执行时间)取决于三个要素:①主频(时钟频率);②CPI;③指令条数。 -
MIPS(Million Instructions Per Second),即每秒执行多少百万条指令。
M I P S = 指令条数 / (执行时间 × 1 0 6 ) = 主频 / ( C P I × 1 0 6 )。 MIPS=指令条数/(执行时间×10^6)=主频/(CPI×10^6)。 MIPS=指令条数/(执行时间×106)=主频/(CPI×106)。
MIPS对不同机器进行性能比较是有缺陷的,因为不同机器的指令集不同,指令的功能也就 不同,比如在机器M1上某条指令的功能也许在机器M2上要用多条指令来完成;不同机器的CPI 和时钟周期也不同,因而同一条指令在不同机器上所用的时间也不同。 -
MFLOPS、GFLOPS、TFLOPS、PFLOPS、EFLOPS和ZFLOPS。
-
MFLOPS(Million Floating-point Operations Per Second),即每秒执行多少百万次浮点运算。
M F L O P S = 浮点操作次数 / (执行时间 × 1 0 6 ) MFLOPS=浮点操作次数/(执行时间×10^6) MFLOPS=浮点操作次数/(执行时间×106) -
GFLOPS(Giga Floating-point Operations Per Second),即每秒执行多少十亿次浮点运算。
G F L O P S = 浮点操作次数 / (执行时间 × 1 0 9 ) GFLOPS=浮点操作次数/(执行时间×10^9) GFLOPS=浮点操作次数/(执行时间×109) -
TFLOPS(Tera Floating-point Operations Per Second),即每秒执行多少万亿次浮点运算。
T F L O P S = 浮点操作次数 / (执行时间 × 1 0 12 ) TFLOPS=浮点操作次数/(执行时间×10^{12}) TFLOPS=浮点操作次数/(执行时间×1012) -
此外,还有PFLOPS=浮点操作次数/(执行时间×1015);EFLOPS=浮点操作次数(执行时间×
1018);ZFLOPS=浮点操作次数/(执行时间×1021)
-
-
-
常用数量单位
- 描述存储容量、文件大小时:K=210,M=220,G=230,T=240
- 描述频率、速率时:K=103,M=106,G=109,T=1012
-
基准程序
基准程序(Benchmarks)是专门用来进行性能评价的一组程序,能够很好地反映机器在运行实际负载时的性能,可以通过在不同机器上运行相同的基准程序来比较在不同机器上的运行时间,从而评测其性能。
1.3.2 几个专业术语
- 系列机。具有基本相同的体系结构,使用相同基本指令系统的多个不同型号的计算机组成的一个产品系列。
- 兼容。指软件或硬件的通用性,即运行在某个型号的计算机系统中的硬件/软件也能应用于另一个型号的计算机系统时,称这两台计算机在硬件或软件上存在兼容性。
- 软件可移植性。指把使用在某个系列计算机中的软件直接或进行很少的修改就能运行在另一个系列计算机中的可能性。
- 固件。将程序固化在ROM中组成的部件称为固件。固件是一种具有软件特性的硬件,吸收了软/硬件各自的优点,其执行速度快于软件,灵活性优于硬件,是软/硬件结合的产物例如,目前操作系统已实现了部分固化(把软件永恒地存储于ROM中)。
2 数据的表示和运算
2.1 数制与编码
2.1.1 进位计数制及其相互转换
-
进位计数法
在进位计数法中,每个数位所用到的不同数码的个数称为基数。十进制的基数为10,逢十进一。
一个r进制数( K n K n − 1 . . . K 0 K − 1 . . . K − m K_nK_{n-1}...K_0K_{-1}...K{-m} KnKn−1...K0K−1...K−m)的数值可表示为:
K n r n + K n − 1 r n − 1 . . . K 0 r 0 + K − 1 r − 1 . . . K − m r − m = ∑ i = n − m K i r i K_nr^n+K_{n-1}r^{n-1}...K_0r^0+K_{-1}r^{-1}...K{-m}r^{-m}=\sum_{i=n}^{-m} {K_ir^i} Knrn+Kn−1rn−1...K0r0+K−1r−1...K−mr−m=i=n∑−mKiri
式中,r是基数ri是第i位的位权(整数位最低位规定为第0位);Ki的取值可以是0,1,…,r-1共r个数码中的任意一个。-
十进制:基数为10,计数“逢十进一”
- 数符:0~9
- 表示:(1652)10 或 1652D
-
二进制:基数为2的计数制;计数“逢二进一”。
-
数符:0、1
-
表示:(1010001010010)2 或 1010001010010B
-
-
八进制。基数为8,计数“逢八进一”。
-
数符:0~7
-
表示:(1652)8
-
-
十六进制:基数为16,“逢十六进一”。
- 数制:0~9、A、B、C、D、E、F,其中A、B、C、D、E、F分别表示10~15。
- 表示:(1652)16 或 1652H 或 0x1652
-
-
不同进制数之间的相互转换
-
二进制数转换为八进制数和十六进制数
二进制转换为八进制:每3个二进制位对应一个八进制位。
二进制转换为十六进制:每4个二进制位对应一个十六进制位。
在转换时以小数点为界,整数部分从右往左数分组,左加零补齐;小数部分从左往右数分组,右加零补齐
例:将二进制数1111000010.01101分别转换为八进制数和十六进制数。
八进制(三位一组):( 001 111 000 010 . 011 010 )2=( 1702.32 )8
十六进制(四位一组):( 0011 1100 0010 . 0110 1000)2=( 3C2.68 )16
同样八进制或十六进制转换为二进制,只需将每位改为3位或4位二进制数即可。
八进制与十六进制转换,需要先转成二进制再转换。
-
任意进制数转换为十进制数
将任意进制数的各位数码与它们的权值相乘,再把乘积相加,就得到了一个十进制数。
例:(11011.1)2=1×24+1×23+0×22+1×21+1×2-1=27.5
-
十进制数转换为任意进制数
基数乘除法:这种转换方法对十进制数的整数部分和小数部分将分别进行处理,对整数部分用除基取余法,对小数部分用乘基取整法,最后将整数部分与小数部分的转换结果拼接起来。
-
除基取余法(整数部分的转换):整数部分除基取余,最先取得的余数为数的最低位,最后取得的余数为数的最高位(即除基取余,先余为低,后余为高),商为0时结束。
-
乘基取整法(小数部分的转换):小数部分乘基取整,最先取得的整数为数的最高位,最后取得的整数为数的最低位(即乘基取整,先整为高,后整为低),乘积为1.0(或满足精度要求)时结束。
注意:在计算机中,小数和整数不一样,整数可以连续表示,但小数是离散的,所以并不是每个十进制小数都可以准确地用二进制表示。例如0.3,无论经过多少次乘二取整转换都无法得到精确的结果。但任意一个二进制小数都可以用十进制小数表示。
-
-
-
真值和机器数
真值:指用正号、负号来分别表示正数(正号可省略)和负数,是机器数所代表的实际值。
机器数:用“0”表示“正”,用“1”表示“负”;这种把符号“数字化”的数称为机器数。常用的有原码、补码和反码表示法。如0,101(这里的逗号“,”仅为区分符号位与数值位)表示+5。
2.1.2 BCD码
二进制编码的十进制数(Binary-Coded Decimal,,BCD)通常采用4位二进制数来表示一位十进制数中的0~9这10个数码。这种编码方法使二进制数和十进制数之间的转换得以快速进行。
但4位二进制数可以组合出16种代码,因此必有6种状态为冗余状态。
-
8421码
它是一种有权码,设其各位的数值为b3,b2,b1,b0,则权值从高到低依次为8,4,2,1。
若两个8421码相加之和小于等于(1001)2即(9)10,则不需修正;若相加之和大于等于(1010)2即(10)10,则要加6修正(从1010到1111这6个为无效码,当运算结果落于这个区间时,需要将运算结果加上6),并向高位进位。
-
余3码
这是一种无权码,是在8421码的基础上加(0011)2形成的,因每个数都多余“3”,因此称为余3码。如8→1011;9→1100。
-
2421码
这也是一种有权码,权值由高到低分别为2,4,2,1,特点是大于或等于5的4位二进制数中最高位为1,小于5的最高位为0。如5→1011而非0101。
2.1.3 定点数的编码表示
-
机器数的定点表示
定点表示法用来表示定点小数和定点整数。符号位为0表示正数,符号位为1表示负数。
-
定点小数:小数点在符号位之后,有效数值部分最高位之前。
当x0=0,x1~xn,均为1时,X为其所能表示的最大正数,真值等于1-2-n;
当x0=1,x1~xn,均为1时,X为其(原码)所能表示的最小负数,真值等于-(1-2-n)
-
定点整数:小数点在有效数值部分最低位之后。
当x0=0,x1~xn,均为1时,X为其所能表示的最大正数,真值等于2n-1;
当x0=1,x1~xn均为1时,X为其(原码)所能表示的最小负数,真值等于-(2n-1)
-
-
原码
用机器数的最高位表示数的符号,其余各位表示数的绝对值。
-
纯整数的原码定义:
若字长为n+1,则原码整数的表示范围为-(2n-1)≤x≤2n-1(关于原点对称)
例如,若x1=+1110,x2=-1110,字长为8位,则其原码表示为[x1]原=0,0001110,[x2]原=27+1110=1,0001110,其中最高位是符号位。
-
纯小数的原码定义:
若字长为n+1,则原码小数的表示范围为-(1-2-n)≤x≤1-2-n(关于原点对称)
例如,若x1=+0.1101,x2=-0.1101,字长为8位,则其原码表示为[x1]原=0.1101000,[x2]原=1-(-0.1101)=1.1101000,其中最高位是符号位。
原码表示的优点是与真值的对应关系简单、直观,与真值的转换简单,并且用原码实现乘除运算比较简便。缺点是,0的表示不唯一,更重要的是原码加减运算比较复杂。
-
-
反码
正数与原码相同;负数与原码相比,符号位不变,数值位按位取反。
-
纯整数的反码
-
纯小数的反码
反码表示存在以下几个方面的不足:0的表示不唯一(即存在正负0);表示范围比补码少个最小负数。反码在计算机中很少使用,通常用作数码变换的中间表示形式。
-
-
补码
正数与原码相同;负数与原码相比,符号位不变,数值位按位取反再加1。
负数手算:从右往左找到第一个1,这个1左边的所有“数值位”按位取反。
-
纯整数的补码定义:
若字长为n+1,则补码的表示范围为-2n≤x≤2n-1(比原码多表示-2n)。
例如,若x1=+1010,x2=-1101,字长为8位,则其补码表示为[x1]补=0,0001010,[x2]补=28-0,0001101=1,1110011。
8位字长,原码取值范围是-127~+127(1111 1111~0111 1111);
补码取值范围是-128~+127(1000 0000~0111 1111),(-128)10=(1000 0000)2
-
纯小数的补码定义:
若字长为n+1,则补码的表示范围为-1≤x≤1-2-n(比原码多表示-1)。
例如,若x1=+0.1001,x2=-0.0110,字长为8位,则其补码表示为[x1]补=0.1001000,[x2]补=2-0.0110=1.1010000。
其中(-1)10=(1000 0000)2
注意:零的补码表示是唯一的,即[+0]=[-0]=0.0000。由定义[-1]=1.0000,可见,小数补码比原码多表示一个“-1”;整数补码比原码多表示一个“-2n"
-
变形补码
变形补码,又称模4补码,双符号位的补码小数,其定义为
模4补码双符号位00表示正,11表示负,用在完成算术运算的ALU部件中。
将[x]补的符号位与数值位一起右移并保持原符号位的值不变,可实现除法功能。
模4补码的优点是可以在运算结果的符号位上直接判断是否发生溢出。
如果两个正数相加之和大于等于1,则符号位为01,表示正数上溢;
如果两个负数相加,而其和小于-1,则符号位为10,表示负数下溢。
-
补码与真值之间的转换
对补码而言,正数和负数的转换不同。正数补码的转换方式与原码的相同。
- 真值转换为补码:对于正数,与原码的方式一样。对于负数,符号位取1,其余各位由真值“各位取反,末位加1”得到。
- 补码转换为真值:若符号位为0,与原码的方式一样。若符号位为1,真值的符号为负,数值部分各位由补码“各位取反,末位加1”得到。
-
-
移码
移码常用来表示浮点数的阶码。它只能表示整数。
移码就是在真值X上加上一个偏置值,通常这个常数取2n,相当于X在数轴上向正方向偏移了若干单位,这就是“移码”一词的由来。移码定义为
[ x ] 移 = 2 n + x ( − 2 n ≤ x < 2 n ,其中机器字长为 n + 1 ) [x]_移=2^n+x(-2^n≤x<2^n,其中机器字长为n+1) [x]移=2n+x(−2n≤x<2n,其中机器字长为n+1)例如,若正数x1=+10101,x2=-10101,字长为8位,则其移码表示为[x1]移=27+10101=1,0010101;[x2]移=27+(-10101)=0,1101011。
移码特点:
- 移码中零的表示唯一,[+0]=[-0]=2n=1000 0000
- 一个真值的移码和补码仅差一个符号位;即补码符号位取反得到移码
- 移码全0时,对应真值的最小值-2n;移码全1时,对应真值的最大值2n-1。
- 移码保持了数据原有的大小顺序,移码大真值就大,移码小真值就小。
-
原码、补码、反码和移码这4种编码表示的总结如下:
-
原码、补码、反码的符号位相同,正数的机器码相同。
-
原码、反码的表示在数轴上对称,二者都存在+0和-0两个零。
-
补码、移码的表示在数轴上不对称,零的表示唯一,它们比原码、反码多表示一个数
-
整数的补码、移码的符号位相反,数值位相同。
-
负数的反码、补码末位相差1。
-
原码很容易判断大小。而负数的反码、补码很难直接判断大小,
可采用如下规则快速判断:对于负数,数值部分越大,绝对值越小,真值越大(更靠近0)。
n+1 bit 合法表示范围 最大值 最小值 真值0 原码 − ( 2 n − 1 ) ≤ x ≤ 2 n − 1 -(2^n-1)≤x≤2^n-1 −(2n−1)≤x≤2n−1 (0,11…1)2=2n-1 (1,11…1)2=-(2n-1) +0=(0,00…0)2
-0=(1,00…0)2反码 − ( 2 n − 1 ) ≤ x ≤ 2 n − 1 -(2^n-1)≤x≤2^n-1 −(2n−1)≤x≤2n−1 (0,11…1)2=2n-1 (1,00…0)2=-(2n-1) +0=(0,00…0)2
-0=(1,11…1)2补码 − 2 n ≤ x ≤ 2 n − 1 -2^n≤x≤2^n-1 −2n≤x≤2n−1 (0,11…1)2=2n-1 (1,00…0)2=-2n 0=(0,00…0)2 移码 − 2 n ≤ x ≤ 2 n − 1 -2^n≤x≤2^n-1 −2n≤x≤2n−1 (1,11…1)2=2n-1 (0,00…0)2=-2n 0=(1,00…0)2 无符号整数 0 ≤ x ≤ 2 n + 1 − 1 0≤x≤2^{n+1}-1 0≤x≤2n+1−1 (1,11…1)2=2n+1-1 (0,00…0)2=0 0=(0,00…0)2 -
2.1.4 整数的表示
-
无符号整数的表示
整个机器字长全部二进制位均为数值位,机器字长n位数的表示范围0~2n-1。
-
带符号整数的表示
最高位为符号位,0正1负。计算机中带符号数用补码表示,n位带符号数取值范围是-2n-1~2n-1-1
2.2 运算方式和运算电路
2.2.1 基本运算部件
在计算机中,运算器由算术逻辑单元(Arithmetic Logic Unit,ALU)、移位器、状态寄存器和通用寄存器组等组成。运算器的基本功能包括加、减、乘、除四则运算,与、或、非、异或等逻辑运算,以及移位、求补等操作。ALU的核心部件是加法器。
-
一位全加器
全加器(FA)是最基本的加法单元,有加数Ai、加数Bi,与低位传来的进位Ci-1共三个输入,有本位和Si与向高位的进位Ci共两个输出。全加器的逻辑表达式如下。
和表达式: S i = A i i ⊕ B i i ⊕ C i − 1 (有奇数个 1 时, S i = 1 ; 否则 S i = 0 ) 进位表达式: C i = A i B i + ( A i i ⊕ B i ) C i − 1 和表达式:S_i=A_i~i~⊕ B_i~i~⊕ C_{i-1}(有奇数个1时,S_i=1;否则S_i=0)\\ 进位表达式:C_i=A_iB_i+(A_i~i~⊕ B_i)C_{i-1} 和表达式:Si=Ai i ⊕Bi i ⊕Ci−1(有奇数个1时,Si=1;否则Si=0)进位表达式:Ci=AiBi+(Ai i ⊕Bi)Ci−1
-
串行进位加法器
把n个全加器相连可得到n位加法器,称为串行进位加法器。串行进位又称行波进位,每级进位直接依赖于前一级的进位,即进位信号是逐级形成的。
图中的加法器实现了两个n位二进制数 A = A n A n − 1 … A 1 A=A_nA_{n-1}…A_1 A=AnAn−1…A1和 B = B n B n − 1 … B 1 B=B_nB_{n-1}…B_1 B=BnBn−1…B1逐位相加的功能,得到的二进制和为 S = S n S n − 1 . . . S 1 S=S_nS_{n-1}...S_1 S=SnSn−1...S1,进位输出为 C n C_n Cn。
例如,当 A = 11 … 11 A=11…11 A=11…11、 B = 00 … 01 B=00…01 B=00…01时,结果输出为 S = 00 … 00 S=00…00 S=00…00且 C n = 1 C_n=1 Cn=1。由于位数有限,高位自动丢失,所以实际是模2n的加法运算。
-
并行进位加法器
多个全加器简单串联,可多位同时加;计算速度取决于进位产生和传递的速度。
令 G i = A i B i G_i=A_iB_i Gi=AiBi, P i = A i ⊕ B i P_i=A_i⊕B_i Pi=Ai⊕Bi,全加器的进位表达式为
C i = G i + P i C i − 1 C_i=G_i+P_iC_{i-1} Ci=Gi+PiCi−1
式中,当 A i A_i Ai与 B i B_i Bi都为1时, C i C_i Ci=1,即有进位信号产生,所以称 A i B i A_iB_i AiBi为进位产生函数(本地进位),用 G i G_i Gi表示。 实现上述逻辑表达式的电路称为先行进位(也称超前进位)部件,简称CLA部件。通过这种进位方式实现的加法器称为全先行进位加法器。因为各个进位是并行产生的,所以是一种并行加法器。
-
带标志加法器
无符号数加法器只能用于两个无符号数相加,不能进行带符号整数的加/减运算。为了能进行带符号整数的加/减运算,还需要在无符号数加法器的基础上增加相应的逻辑门电路,使得加法器不仅能计算和/差,还要能生成相应的标志信息。
-
OF(Overflow Flag)溢出标志
含义:有符号数的加减运算是否发生了溢出。溢出时为1,否则置0。
硬件的计算方法:OF=最高位产生的进位⊕次高位产生的进位
注意:OF位对无符号数的加减法无意义
-
SF(Sign Flag)符号标志
含义:有符号数加减运算结果的正负性,结果为负时置1,否则置0。
硬件的计算方法:SF=最高位的本位和
注意:SF位对无符号数的加减法无意义
-
ZF(Zero Flag)零标志
含义:表示运算结果是否为0。运算结果为0时ZF位置1,否则置0。
硬件的计算方法:两个数的运算结果为n bit,只有n bit全为0时,ZF=1
-
CF(Carry Flag)进位/借位标志
含义:进位/借位标志,表示无符号数的加减法是否发生了进位或借位。进位/借位时置1,否则置0。
硬件的计算方法:CF=最高位产生的进位⊕sub(sub=1表示减法;sub=0表示加法)
注意:CF位对有符号数的加减法无意义
-
-
算术逻辑单元(ALU)
ALU是一种功能较强的组合逻辑电路,它能进行多种算术运算和逻辑运算。
由于加、减、乘、除运算最终都能归结为加法运算,因此ALU的核心是带标志加法器,同时也能执行“与”“或”“非”等逻辑运算。
ALU的基本结构如图所示,其中A和B是两个n位操作数输入端,Cin是进位输入端,ALUop是操作控制端,用来决定ALU所执行的处理功能。ALUop的位数决定了操作的种类。
2.2.2 定点数的移位运算
-
算术移位
算术移位的对象是有符号数,在移位过程中符号位保持不变。
-
原码
符号位保持不变,仅对数值位进行移位。左移丢1,运算出错;右移丢1,影响精度。
左移相当于×2;右移相当于÷2。由于位数有限,因此有时候无法用算数移位精确地等效乘除法、
-
反码
- 正数 右移:高位补0,低位舍弃。左移:低位补0,高位舍弃
- 负数 右移:高位补1,低位舍弃。左移:低位补1,高位舍弃。
-
补码
- 正数 右移:高位补0,低位舍弃。左移:低位补0,高位舍弃
- 负数 右移(同反码):高位补1,低位舍弃。左移(同原码):低位补0,高位舍弃。
-
-
逻辑移位
逻辑移位将操作数视为无符号数。
移位规则:逻辑左移时,高位移丢,低位添0:逻辑右移时,低位移丢,高位添0。
-
循环移位
循环移位分为带进位标志位CF的循环移位(大循环)和不带进位标志位的循环移位(小循环)。
循环移位操作特别适合将数据的低字节数据和高字节数据互换。
2.2.3 顶点数的加减运算
-
补码的加减运算
n bit补码X+Y:按位相加即可;n bit补码X-Y:将减数Y全部按位取反,末位+1,得到[-Y]补,减法变加法
特点:
- 1)按二进制运算规则运算,逢二进一。
- 2)若做加法,两数的补码直接相加:若做减法,则将被减数与减数的机器负数相加。
- 3)符号位与数值位一起参与运算,加、减运算结果的符号位也在运算中直接得出。
- 4)最终运算结果的高位丢弃,保留n+1位,运算结果亦为补码。
-
补码加减运算电路
进行补码的 X + Y X+Y X+Y运算, Y Y Y为负数则补码为 Y ˉ + 1 \bar Y+1 Yˉ+1,因此使用MUX2选1多路选择器,用一个控制端Sub来控制,选择 Y Y Y还是 Y ˉ \bar Y Yˉ输入加法器,并将Sub作为低位同时送入加法器。
当Sub为1时,做减法,实现 X + Y ˉ + 1 = [ x ] 补 + [ − y ] 补 X+\bar Y+1=[x]_补+[-y]_补 X+Yˉ+1=[x]补+[−y]补;当Sub=0时,做加法,实现 X + Y = [ x ] 补 + [ y ] 补 X+Y=[x]_补+[y]_补 X+Y=[x]补+[y]补
-
溢出判别方法
仅当两个符号相同的数相加或两个符号相异的数相减才可能产生溢出,如两个正数相加,而结果的符号位却为1(结果为负);一个负数减去一个正数,结果的符号位却为0(结果为正)。
-
采用一位符号位
只要参加操作的两个数符号相同,结果又与原操作数符号不同,则表示结果溢出。
-
采用一位符号位,根据数据位进位情况判断溢出
若符号位的进位Cs与最高数位的进位C1相同,则说明没有溢出,否则表示发生溢出。
-
采用双符号位(模4补码)
运算结果的两个符号位Ss1Ss2相同,表示未溢出;运算结果的两个符号位Ss1Ss2不同,表示溢出,此时最高位符号位代表真正的符号。
-
-
符号扩展
定点数表示的数转换成具有不同位数的某种表示形式。其根本目的是:表示的数值保持不变。
- 对于正数:新表示形式的所有附加位都用0进行填充
- 对于负数:
- 符号位保持不变,原码的所有附加位都用0进行填充;
- 符号位保持不变,反码的所有附加位都用1进行填充;
- 符号位保持不变,补码的所有附加位都用1(对于整数)或0(对于小数)进行填充
2.2.4 定点数的乘除运算
-
定点数的乘法运算
乘法运算由累加和右移操作实现,可分为原码一位乘法和补码一位乘法。
-
原码一位乘法
符号位与数值单独计算。
- 符号位=x⊕y,通过异或确定。
- 数值部分通过被乘数和乘数绝对值的n轮加法、移位完成。
下图为手算乘法例子:
计算机无符号相乘类似于手算,但是有以下改变:
- 部分积:每将乘数Y的一位乘以被乘数得X×Yi后,就将该结果与前面所得的结果累加,得到Pi,称为部分积。
- 部分积右移:在每次求得X×Yi后,不是将它左移与前次部分积Pi相加,而是将部分积Pi右移相加。
因为每次进行加法运算时,只需要将X×Yi与部分积中的高n位进行相加,低n位不会改变,因此,只需用n位加法器就可实现两个n位数的相乘。
部分积Pi和X进行无符号数相加,可能会产生进位,因而需要有一个专门的进位位C。整个迭代过程从乘数最低位Yn和P0=0开始,经过次“判断-加法-右移”循环,直到求出Pn为止,Pn就是最终的乘积。假定每次循环在一个时钟周期内完成,则n位乘法需要用n个时钟周期来完成。
下图为两个32位无符号数乘法逻辑图。
-
被乘数寄存器X用于存放被乘数;
-
乘数寄存器P开始时置初始部分积P0=0,结束时存放的是64位乘积的高32位;
-
乘数寄存器Y开始时置乘数,结束时存放64位乘积的低32位。
-
进位触发器C保存加法器进位信号;
-
**计数器Cn**存放循环次数,初值为32(n位乘法时为n),每循环一次,Cn减1,直到0结束。
-
ALU在控制逻辑下,对乘积寄存器P和被乘数寄存器X的内容进行加运算,结果存到乘法寄存器P中,进位位存放在进位触发器C中。
每次循环都要对进位位C、乘积寄存器P和乘数寄存器Y实现同步“右移”,此时,进位信号C移入寄存器P的最高位,寄存器P的最低位移出到寄存器Y的最高位,寄存器Y的最低位移出,0移入进位位C中。
-
补码一位乘法(Booth算法)
这是一种有符号数的乘法,采用相加和相减操作计算补码数据的乘积。
设 [ X ] 补 = x s . x 1 x 2 . . . x n , [ Y ] 补 = y s . y 1 y 2 . . . y n [X]_补=x_s.x_1x_2...x_n,[Y]_补=y_s.y_1y_2...y_n [X]补=xs.x1x2...xn,[Y]补=ys.y1y2...yn,运算规则如下:
-
①符号位参与运算,运算的数均以补码表示。
-
②被乘数一般取双符号位参与运算,部分积取双符号位,初值为0,乘数取单符号位。
-
③乘数末位增设附加位yn+1,初值为0。
-
④根据(yn,yn+1)的取值来确定操作,见表。
-
⑤移位按补码右移规则进行。
-
⑥按照上述算法进行n+1步操作,但第n+1步不再移位(共进行n+1次累加和n次右移),仅根据yn与yn+1的比较结果做相应的运算。
无符号数乘法逻辑图如下所示,相比无符号数少了进位位,多了辅助位。
运算过程如图:
-
-
-
定点数的除法运算
除法运算可转换成“累加一左移”(逻辑左移),分为原码除法和补码除法。
-
原码除法运算(不恢复余数法)
商符和商值是分开进行的,减法操作用补码加法实现,商符由两个操作数的符号位“异或”形成。
手算除法过程:
除法运算逻辑结构如图所示:
- 除数寄存器Y中存放除数。
- 余数寄存器R开始时置被除数的高32位,作为初始中间余数R0的高位部分,结束时存放的是余数。
- 余数/商寄存器Q开始时置被除数的低32位,作为初始中间余数R0的低位部分,结束时存放的是32位商,在运算过程中,Q中存放的并不是商的全部位数,而是部分为被除数或中间余数,部分为商,只有到最后一步才是商的全部位数。
- 计数器Cn存放循环次数,初值是32,每循环一次,Cn减1,当Cn=0时,除法运算结束
- ALU是除法器核心部件,在控制逻辑控制下,对于余数寄存器R和除数寄存器Y的内容进行“加/减”运算,在“写使能”控制下运算结果被送回寄存器R。
每次循环都要对寄存器R和Q实现同步左移,左移时,Q的最高位移入R的最低位,Q中空出的最低位上被上商。从低位开始,逐次把商的各个数位左移到Q中。每次由控制逻辑根据ALU运算结果的符号位来决定上商为0还是1。
运算过程:正1减,负0加
设 被除数 [ X ] 补 = x s . x 1 x 2 . . . x n , 除数 [ Y ] 补 = y s . y 1 y 2 . . . y n 被除数[X]_补=x_s.x_1x_2...x_n,除数[Y]_补=y_s.y_1y_2...y_n 被除数[X]补=xs.x1x2...xn,除数[Y]补=ys.y1y2...yn,运算规则如下:
-
① 商的符号: Q s = x s ⊕ Y s Q_s=x_s⊕Y_s Qs=xs⊕Ys;② 商的数值: ∣ Q ∣ = ∣ X ∣ / ∣ Y ∣ |Q|=|X|/|Y| ∣Q∣=∣X∣/∣Y∣
-
先用被除数减去除数 ( ∣ X ∣ − ∣ Y ∣ = ∣ X ∣ + ( − ∣ Y ∣ ) = ∣ X ∣ + [ − ∣ Y ∣ 补 ] ) (|X|-|Y|=|X|+(-|Y|)=|X|+[-|Y|_补]) (∣X∣−∣Y∣=∣X∣+(−∣Y∣)=∣X∣+[−∣Y∣补]),当余数为正时,商1,余数和商左移1位,再减去|除数|;当余数为负时,商上0,余数和商左移1位,再加上|除数|。
-
当第n+1步余数为负时,需加上|Y|得到第n+1步正确的余数(余数与被除数同号)。
设 [ x ] 原 = 0.1011 , [ y ] 原 = 1.1101 [x]_原=0.1011,[y]_原=1.1101 [x]原=0.1011,[y]原=1.1101,用不恢复余数法计算 [ x / y ] 原 [x/y]_原 [x/y]原
商的符号位:0⊕1=1。先计算出X=0.1011,Y=0.1101,-Y=[-|y|补]=1.0011
商的最高位为0,没有溢出,数值为1101,所以[x/y]=1.1101。余数为0.0111×2-4。
-
补码除法运算(加减交替法)
符号位与数值位一起参加运算,商符自然形成。
除法第一步根据被除数和除数的符号决定是做加法还是减法;上商的原则根据余数和除数的符号位共同决定,同号上商“1”,异号上商“0”:最后一步商恒置“1”。
加减交替法的规则如下:同1减,异0加
- ①符号位参加运算,除数与被除数均用补码表示,商和余数也用补码表示。
- ②若被除数与除数同号,则被除数减去除数:若被除数与除数异号,则被除数加上除数。
- ③若余数与除数同号,则商上1,余数左移一位减去除数:若余数与除数异号,则商上0,余数左移一位加上除数。
- ④重复执行第③步操作n次。
- ⑤若对商的精度没有特殊要求,则一般采用“末位恒置1”法。
-
2.2.5 C语言中的整数类型及类型转换
-
有符号数和无符号数的转换
转换只改变数值,而两个变量对应的每位都是一样的。
-
不同字长整数之间的转换
- 长整数变短整数:高位截断,保留低位。
- 短整数变长整数:符号扩展。
2.2.6 数据的存储和排列
-
大端方式和小端方式
在存储数据时,数据从低位到高位可以按从左到右排列,也可以按从右到左排列。因此,无法用最左或最右来表征数据的最高位或最低位。
通常用**最低有效字节(LSB)和最高有效字节(MSB)**来分别表示数的低位和高位。例如,在32位计算机中,一个int型变量i的机器数为01234567H,其最高有效字节MSB=01H,最低有效字节LSB=67H。
- 大端方式按从最高有效字节到最低有效字节的顺序存储数据,即最高有效字节存放在前面
- 小端方式按从最低有效字节到最高有效字节的顺序存储数据,即最低有效字节存放在前面
-
数据按“边界对齐”方式存储
假设存储字长为32位,可按字节、半字和字寻址。对于机器字长为32位的计算机,数据以边界对齐方式存放,半字地址一定是2的整数倍,字地址一定是4的整数倍,这样无论所取的数据是字节、半字还是字,均可一次访存取出。
例如,“字节1、字节2、字节3、半字1、半字2、半字3、字1”的数据按序存放在存储器中,按边界对齐方式和不对齐方式存放时,如图所示。
边界对齐方式相对边界不对齐方式是一种空间换时间的思想。精简指令系统计算机RISC通常采用边界对齐方式,因为对齐方式取指令时间相同,因此能适应指令流水。
2.3 浮点数的表示与运算
2.3.1 浮点数的表示
-
浮点数的表示格式
通常,浮点数表示为
N = ( − 1 ) S × M × R E N=(-1)^S×M×R^E N=(−1)S×M×RE- 数符S取值0或1,用来决定浮点数的符号
- 尾数M是一个二进制定点小数,一般用定点原码小数表示
- 阶数E是一个二进制定点整数,又称指数,用移码表示
- 基数R是隐含的,可以约定为2、4、8、16等
下图为一个32位浮点数格式:
其中,第0位为数符S;第1~7位为移码表示的阶码E(偏置值为64);第8~31位为24位二进制原码小数表示的尾数M;基数R为2。
-
阶码的值反映浮点数的小数点的实际位置
-
阶码的位数反映浮点数的表示范围
-
尾数的位数反映浮点数的精度。
-
浮点数的表示范围
原码是关于原点对称的,故浮点数的范围也是关于原点对称的。
-
上溢:运算结果大于最大正数时称为正上溢,小于绝对值最大负数时称为负上溢,正上溢和负上溢统称上溢。数据一旦产生上溢,计算机必须中断运算操作,进行溢出处理。
-
下溢:当运算结果在0至最小正数之间时称为正下溢,在0至绝对值最小负数之间时称为负下溢,正下溢和负下溢统称下溢。数据下溢时,浮点数值趋于零,计算机仅将其当作机器零处理。
-
-
浮点数的规格化
尾数的位数决定浮点数的有效数位,有效数位越多,数据的精度越高。
规格化操作:是指通过调整一个非规格化浮点数的尾数和阶码的大小,使非零的浮点数在尾数的最高数位上保证是一个有效值。
- 左规:当运算结果的尾数的最高数位不是有效位,即出现±0.0…0×…×的形式时,需要进行左规。左规时,尾数每左移一位、阶码减1(基数为2时)。左规可能要进行多次。
- 右规:当运算结果的尾数的有效位进到小数点前面时,需要进行右规。将尾数右移一位、阶码加1(基数为2时)。需要右规时,只需进行一次。
规格化浮点数的尾数M的绝对值应满足 1 / R ≤ ∣ M ∣ < 1 1/R≤|M|<1 1/R≤∣M∣<1。若R=2,则有 1 / 2 ≤ ∣ M ∣ < 1 1/2≤|M|<1 1/2≤∣M∣<1。原码表示的规格化尾数的形式如下:
- 正数最大值为0.11…1,最小值为0.10…0。尾数表示范围为 1 / 2 ≤ ∣ M ∣ ≤ ( 1 − 2 − n ) 1/2≤|M|≤(1-2^{-n}) 1/2≤∣M∣≤(1−2−n)。
- 负数最大值为1.10…0,最小值为1.11…1。尾数表示范围为 − ( 1 − 2 − n ) ≤ M ≤ − 1 / 2 -(1-2^{-n})≤M≤-1/2 −(1−2−n)≤M≤−1/2。
补码表示的尾数规格化:尾数最高数值位必须和尾数符号位相反。
-
IEEE754标准
按照IEEE754标准,常用的浮点数的格式如图所示。
IEEE754偏置值,如下表所示。
偏置值指阶码部分,以移码表示时的偏置值,也就是表示为0的值。阶码值=阶码的原码值-偏置值。
尾数默认规格化二进制浮点数,隐藏最高位为1,称为隐藏位。
例如,(12)10=(1100)2,将它规格化后结果位1.1×23,其中整数部分的1将不存储与尾数。
因此,用IEEE754方式表示12,阶码=3,用移码表示为127+3=130=(1000 0010)2;尾数为.1。
用IEEE754表示为0100 0001 0100 0000 … 0000即41 40 00 00 H 。
IEEE754标准中,规格化的短浮点数的真值为
( − 1 ) S × 1. M × 2 E − 127 (-1)^S×1.M×2^{E-127} (−1)S×1.M×2E−127
长浮点数真值为
( − 1 ) S × 1. M × 2 E − 1023 (-1)^S×1.M×2^{E-1023} (−1)S×1.M×2E−1023
式中,短浮点数E的取值为1~254(8位表示),M为23位,共32位:长浮点数E的取值为1~2046(11位表示),M为52位,共64位。IEEE754浮点数范围:
格式 最小值 最大值 单精度 E=1,M=0
1.0×21-127=2-126E=254,M=.111…
1.111…1×2254-127=2127×(2-2-23)双精度 E=1,M=0
1.0×21-1023=2-1022E=2046,M=.111…
1.111…1×22046-1023=21023×(2-2-52)对于IEEE 754格式的浮点数,阶码全0或全1时,有其特别的解释
- 全0阶码全0尾数:+0/-0。零的符号取决于数符S,一般情况下+0和-0是等效的。
- 全1阶码全0尾数:+∞/-∞。+∞在数值上大于所有有限数,-∞则小于所有有限数。
- 全0阶码不全0尾数,表示非规格化小数
- 全1阶码不全0尾数,表示非数值NaN(Not a Number)
例:IEEE754格式转换为十进制
例:十进制转换为IEEE754格式
-
定点、浮点表示的区别
-
1)数值的表示范围
若定点数和浮点数的字长相同,则浮点表示法所能表示的数值范围远大于定点表示法。
-
2)精度
对于字长相同的定点数和浮点数来说,浮点数虽然扩大了数的表示范围,但精度降低了。
-
3)数的运算
浮点数包括阶码和尾数两部分,运算时不仅要做尾数的运算,还要做阶码的运算,面且运算结果要求规格化,所以浮点运算比定点运算复杂。
-
4)溢出问题
在定点运算中,当运算结果超出数的表示范围时,发生溢出:浮点运算中,运算结果超出尾数表示范围却不一定溢出,只有规格化后阶码超出所能表示的范围时,才发生溢出。
-
2.3.2 浮点数的加减运算
浮点数运算的特点是阶码运算和尾数运算分开进行,浮点数加减运算分为以下5步。
-
对阶
对阶的目的是使两个操作数的小数点位置对齐,即使得两个数的阶码相等。
为此,先求阶差然后以小阶向大阶看齐的原则,将阶码小的尾数右移一位(基数为2),阶加1,直到两个数的阶码相等为止。尾数右移时,舍弃掉有效位会产生误差,影响精度。
-
尾数求和
将对阶后的尾数按定点数加(减)运算规则运算。运算后的尾数不一定是规格化的,因此,浮点数的加减运算需要进一步进行规格化处理。
-
规格化
IEEE754规格化尾数的形式为±1.×…×。尾数相加减后会得到各种可能结果,例如:
1. × … × + 1. × … × = ± 1 × . × … × ① 1. × … × − 1. × … × = ± 0.0 … 01 × … × ② 1.×…×+1.×…×=±1×.×…×①\\ 1.×…×-1.×…×=±0.0…01×…×② 1.×…×+1.×…×=±1×.×…×①1.×…×−1.×…×=±0.0…01×…×②- 右归:当结果如①时,进行右归。尾数右移一位,阶码加1。尾数右移时,最高位1被移到小数点前一位作为隐藏位,最后一位移除时,考虑舍入。
- 左归:当结果位②时,进行左归。尾数每左移一位,阶码减1。可能需要左规多次,直到将第一位1移到小数点左边。
①左规一次相当于乘2,右规一次相当于除2;②需要右规时,只需进行一次。
-
舍入
在对阶和尾数右规时,可能会对尾数进行右移,为保证运算精度,一般将低位移出的两位保留下来,参加中间过程的运算,最后将运算结果进行舍入,还原表示成IEEE754格式。
- 0舍1入法:类似于十进制的“四舍五入”法。运算结果保留位的最高数位为0,则舍去;最高数位为1,则在尾数的末位加1。这样可能会使尾数溢出,此时需再做一次右规。
- 恒置1法:不论丢掉的最高数位是0还是1,都把右移后的尾数末位恒置1。
- 截断法:直接截取所需位数,丢弃后面的所有位,这种舍入处理最简单。
-
溢出判断
在尾数规格化和尾数舍入时,可能会对阶码执行加/减运算。因此,必须考虑指数溢出的问题。
指数上溢:若一个正指数超过了最大允许值(127或1023),则发生指数上溢,产生异常。
- 右规和尾数舍入。数值很大的尾数舍入时,可能因为末位加1而发生尾数溢出,此时需要通过右规来调整尾数和阶。右规时阶加1,导致阶增大,因此需要判断是否发生了指数上溢。当调整前的阶码为11111110时,加1后,会变成11111111而发生指数上溢。
指数下溢:若一个负指数超过了最小允许值(-126或-1022),则发生指数下溢,通常把结果按机器零处理。
- 左规。左规时阶减1,导致阶减小,因此需要判断是否发生了指数下溢。其判断规则与指数上溢类似,左规一次,阶码减1,然后判断阶码是否为全0来确定是否指数下溢。
-
C语言中的浮点数类型
C语言中的float和double类型分别对应于IEEE 754单精度浮点数和双精度浮点数。
-
无损:char->int->long->double;float->double
范围、精度从小到大,转换过程没有损失
-
有损:
int->float:可能会损失精度(float尾数的数值位有1隐藏位+23尾数位)
float->int:可能会溢出,也可能会损失精度(如小数转整数)
-
3 存储系统
3.1 存储器概述
3.1.1 存储器的分类
-
按在计算机中的作用(层次)分类
- 1)主存储器。简称主存,又称内存储器(内存),用来存放计算机运行期间所需的程序和数据,CPU可以直接随机地对其进行访问,也可以和高速缓冲存储器(Cache)及辅助存储器交换数据。其特点是容量较小、存取速度较快、每位的价格较高。
- 2)辅助存储器。简称辅存,又称外存储器(外存),用来存放当前暂时不用的程序和数据,以及一些需要永久性保存的信息。辅存的内容需要调入主存后才能被CPU访问。其特点是容量大、存取速度较慢、单位成本低。
- 3)高速缓冲存储器。简称Cache,位于主存和CPU之间,用来存放当前CPU经常使用的指令和数据,以便CPU能高速地访问它们。Cache的存取速度可与CPLU的速度相匹配,但存储容量小、价格高。现代计算机通常将它们制作在CPU中。
存储系统层次结构主要体现在缓存一主存和主存一辅存这两个存储层次上
- 缓存-主存层次主要解决CPU和主存速度不匹配的问题。
- 主存-辅存层次主要解决存储系统的容量问题。
-
按存储介质分类
- 半导体存储器:以半导体器件存储信息;主存、Cache
- 磁表面存储器:以磁性材料存储信息;磁盘、磁带
- 光存储器:光盘
-
按存取方式分类
-
随机存储器(RAM)
存储器的任何一个存储单元都可以随机存取,而且存取时间与存储单元的物理位置无关。
- 静态RAM:触发器原理寄存信息
- 动态RAM:电容充电原理寄存信息
优点:读写方便,使用灵活,主要用于主存或高速缓重存储器
-
只读存储器(ROM)
存储器的内容只能随机读出而不能写入。ROM一旦有了信息则不能轻易改变,即使断电也不会丢失。
- 掩膜式只读存储器(MROM)
- 一次可编程只读存储器(PROM)
- 可擦除可编程只读存储器(EPROM):不能取代RAM,因为编程次数有限,且写入速度很慢
- 闪速存储器(Flash Memory):由E2ROM发展得到;应用U盘。
- 固态硬盘(SSD)
-
相联存储器(CAM)
不根据地址而是根据存储内容和指定地址方式来进行存取的存储器,可以实现快速地查找快表
-
串行访问存储器
对存储单元进行读/写操作时,需按其物理位置的先后顺序寻址。
-
顺序存取存储器(SAM):内容只能顺序读取,存取时间长短与信息在存储体上的物理位置有关;
如磁带。
- 优点是结构简单,成本低廉,容量大,适合于存放顺序访问的信息。
- 缺点是存取速度慢,不方便随机访问。
-
直接存取存储器(DAM):内容可以直接读取,存取时间与信息在存储体上的物理位置无关;
如磁盘、光盘;
- 优点是存取速度快,方便随机访问。
- 缺点是结构复杂,成本较高,容量有限,适合于存放长期随机访问的信息。
-
-
-
按信息的可保存性分类
- 易失性存储器:RAM、主存、Cache
- 非易失性存储器:ROM、磁表面存储器、光存储器
- 破坏性读出:信息读出后,原存储信息被破坏;如DRAM芯片,读出数据后要进行重写
- 非破坏性读出:信息读出后,原存储信息不被破坏;如SRAM芯片、磁盘、光盘
-
信息的可更改性
- 读写存储器(Read/Write Memory):即可读、也可写(如:磁盘、内存、Cache)
- 只读存储器(Read Only Memory):只能读,不能写(如:实体音乐专辑通常采用CD-RGM,实体电影采用蓝光光碟,BIOS通常写在ROM中。)
3.1.2 存储器性能指标
-
存储容量
存储容量 = 存储字数 × 字长 存储容量=存储字数×字长 存储容量=存储字数×字长
存储字数表示存储器的地址空间大小,字长表示一次存取操作的数据量。 -
单位成本
每位价格 = 总成本 / 总容量 每位价格=总成本/总容量 每位价格=总成本/总容量 -
存储速度
数据传输率 = 数据的宽度 / 存储周期 数据传输率=数据的宽度/存储周期 数据传输率=数据的宽度/存储周期-
存取时间(Ta):从启动一次存储器操作到完成该操作经历的时间;从存储器读出或写入一次信息所需要的平均时间;分为读出时间和写入时间
存取时间不等于存储周期,通常存取周期大于存取时间
-
存取周期(Tm)/读写周期/访问周期:存储器进行一次完整的读写操作所需的全部时间;连续两次独立访问存储器操作(读或写操作)之间所需的最小时间间隔
-
主存带宽(Bm)/数据传输率:每秒从主存进入信息的最大数量;单位为字/秒、字节/秒(B/s)或位/秒(b/s)。
-
3.2 主存储器
主存储器由DRAM实现,靠处理器的那一层(Cache)则由SRAM实现,它们都属于易失性存储器,只要电源被切断,原来保存的信息便会丢失。
DRAM的每位价格低于SRAM,速度也慢于SRAM,价格差异主要是因为制造SRAM需要更多的硅。
3.2.1 SRAM芯片和DRAM芯片
通常把存放一个二进制位的物理器件称为存储元,它是存储器的最基本的构件。地址码相同的多个存储元构成一个存储单元。若干存储单元的集合构成存储体。
-
SRAM工作原理
静态随机存储器(SRAM)的存储元是用双稳态触发器(六晶体管MOS)来记忆信息的,因此即使信息被读出后,它仍保持其原状态而不需要再生(非破坏性读出)。
上图为双稳态触发器。若T2管导通,则T1管一定截止,此时A点为高电平,B电为低电平,假定此时为存1状态;反之(当T1管导通时)则为存0状态。
SRAM的存取速度快,但集成度低,功耗较大,价格昂贵,只要不断电,触发器的状态就不会改,一般用于高速缓冲存储器。
应用Cache。
-
DRAM工作原理
动态随机存储器(DRAM)是利用存储元电路中栅极电容上的电荷来存储信息的,DRAM的基本存储元通常只使用一个晶体管,所以它比SRAM的密度要高很多。
读出1:MOS管接通,电容放电,数据线上产生电流;读出0:MOS管接通后,数据线上无电流
电容放电信息被破环,是破坏性读出。读出后应有重写操也称“再生”;读写速度慢;每个存储元制造成本更低,集成度高,功耗低。
电容内的电荷只能维持2ms。即便不断电,2ms后信息也会消失;2ms之内必须“刷新”一次(给电容充电);每次刷新一行存储单元。
-
集中刷新:指在一个刷新周期内,利用一段固定的时间,依次对存储器的所有行进行逐一再生,在此期间停止对存储器的读写操作,称为“死时间”,又称访存“死区”。
- 优点:读写操作时不受刷新工作的影响;
- 缺点:在集中刷新期间(死区)不能访问存储器。
-
分散刷新:把对每行的刷新分散到各个工作周期中。这样,一个存储器的系统工作周期分为两部分:前半部分用于正常读、写或保持;后半部分用于刷新。这种刷新方式增加了系统的存取周期,如存储芯片的存取周期为0.5μs,则系统的存取周期为1μs。
- 优点是没有死区;
- 缺点是加长了系统的存取周期,降低了整机的速度。
-
异步刷新:异步刷新是前两种方法的结合,它既可缩短“死时间”,又能充分利用最大刷新间隔为2ms的特点。具体做法是将刷新周期除以行数,得到两次刷新操作之间的时间间隔t,利用逻辑电路每隔时间t产生一次刷新请求。
这样可以避免使CPU连续等待过长的时间,而且减少了刷新次数,从根本上提高了整机的工作效率。
-
-
DRAM芯片的读写周期
-
SRAM和DRAM的比较
特点 SRAM DRAM 存储信息 触发器 电容 破坏性读出 非 是 需要制新 不要 需要 送行列地址 同时送 分两次送 运行速度 快 慢 集成度 低 高 存储成本 高 低 主要用途 高速缓存 主机内存 -
存储器芯片的内部结构
存储器芯片由存储体、I/O读写电路、地址译码和控制电路等部分组成。下图为存储芯片结构图。
-
存储体(存储矩阵)。存储体是存储单元的集合,它由行选择线(X)和列选择线(Y)来选择所访问单元,存储体的相同行、列上的位同时被读出或写入。
-
地址译码器。用来将地址转换为译码输出线上的高电平,以便驱动相应的读写电路。
目前DRAM大多采用双译码结构,如下图所示。
采用地址线复用技术,使用行列地址双译码结构,行、列地址分两次送,是为了减少选通线数量。
若有28个芯片,单地址译码需要256条选通线,而双地址译码只需要24+24=32条选通线。
-
I/O控制电路。用以控制被选中的单元的读出或写入,具有放大信息的作用。
-
片选控制信号。单个芯片容量太小,往往满足不了计算机对存储器容量的要求,因此需用一定数量的芯片进行存储器的扩展。在访问某个字时,必须“选中”该存储字所在的芯片,而其他芯片不被“选中”,因此需要有片选控制信号。
-
读/写控制信号。根据CPU给出的读命令或写命令,控制被选中单元进行读或写。
-
3.2.2 只读存储器
-
只读存储器(ROM)的特点
ROM中一旦有了信息,就不能轻易改变,即使掉电也不会丢失。
- 1)结构简单,所以位密度比可读写存储器的高。
- 2)具有非易失性,所以可靠性高。
-
ROM的类型
-
掩膜式只读存储器(MROM)
厂家按照客户需求,在芯片生产过程中直接写入信息,之后任何人不可重写(只能读出)
可靠性高、灵活性差、生产周期长、只适合批量定制
-
一次可编程只读存储器(PROM)
用户可用专门的PROM写入器写入信息,写一次之后就不可更改
-
可擦除可编程只读存储器(EPROM)
EPROM不仅可以由用户利用编程器写入信息,而且可以对其内容进行多次改写。
不能取代RAM,因为编程次数有限,且写入速度很慢(写入前要先擦除)
- UVEPROM(ultraviolet rays)–用紫外线照射8~20分钟,擦除所有信息
- EEPROM(也常记为E2PROM,第一个E是Electrically)–可用“电擦除”的方式,擦除特定的字
-
闪速存储器(Flash Memory)
在EEPROM基础上发展而来,断电后也能保存信息,且可进行多次快速擦除重写
注意:由于闪存需要先擦除在写入,因此闪存的**“写”速度要比“读”速度更慢**。
每个存储元只需单个MOS管,位密度比RAM高。
应用:U盘、SD卡
-
固态硬盘(SSD)
由控制单元+存储单元(Flash芯片)构成,与闪速存储器的核心区别在于控制单元不一样,但存储介质都类似,可进行多次快速擦除重写。
SSD速度快、功耗低、价格高。目前个人电脑上常用SSD取代传统的机械硬盘。
-
3.2.3 主存储器的基本组成
下图是主存储器的基本组成框图,其中由一个个存储0或1的记忆单元(也称存储元件)构成的存储矩阵(也称存储体)是存储器的核心部分。存储单元进行编号,现代计算机按字节编址。
CPU访问主存过程:
- CPU首先把被访问单元的地址送到MAR中;通过地址线将主存地址送到主存中的地址寄存器,以便地址译码器进行译码选中相应单元
- CPU将读写信号通过控制线送到主存的读写控制电路
- 写操作:CPU同时将要写的信息送到MDR中,在读写控制电路的控制下,经数据线将信号写入选中的单元
- 读操作:主存读出选中单元的内容送到数据线,然后送到MDR中
数据线的宽度与MDR的宽度相同,地址线的宽度与MAR的宽度相同。地址线的位数决定了主存地址空间的最大可寻址范围。例如,36位地址的最大寻址范围为0~236-1,即地址从0开始编号。
例1:某一SRAM芯片,其容量为1024×8位,除电源和接地端外,该芯片的引脚的最小数目为()
按字节(8位)取地址,需要8位数据线;共有1024=210个存储单元,SRAM不复用地址线,需要10位地址线;还需要1片选线,2位读写控制线,共8+10+1+2=21位
例2:某一DRAM芯片,其容量为1024×8位,除电源和接地端外,该芯片的引脚的最小数目为()
DRAM复用地址线,分两次传递地址,地址线减半,需要5位地址线;片选线需要行选通线和列选通线,增加到2根,共8+5+2+2=17
注意SRAM和DRAM的区别,DRAM采用地址复用技术,而SRAM不采用。
3.2.4 双端口RAM和多模块存储器
-
双端口RAM
双端口顾名思义就是存储器芯片提供两个端口给两个CPU进行访问。
两个端口对同一主存操作有以下4种情况:
- 1.两个端口不同时对同一地址单元存取数据。成功。
- 2.两个端口同时对同一地址单元读出数据。成功。
- 3.两个端口同时对同一地址单元写入数据。写入错误。
- 4.两个端口同时对局一地址单完,二个写入数据,另一不读出数据。读出错误。
解决办法:
置“忙”信号为0,由判断逻辑决定暂时关闭一个端口(即被延时),未被关闭的端口正常访问,被关闭的端口延长一个很短的时间段后再访问。
-
单体多字存储器
单体多字系统的特点是存储器中只有一个存储体,每个存储单元存储m个字,总线宽度也为m个字。一次并行读出m个字,地址必须顺序排列并处于同一存储单元。
单体多字系统在一个存取周期内,从同一地址取出m条指令,然后将指令逐条送至CPU执行,即每隔1/m存取周期,CPU向主存取一条指令。这显然提高了单体存储器的工作速度。
缺点:指令和数据在主存内必须是连续存放的,一旦遇到转移指令,或操作数不能连续存放,这种方法的效果就不明显。
-
多体并行存储器
多体并行存储器由多体模块组成。每个模块都有相同的容量和存取速度,各模块都有独立的读写控制电路、地址寄存器和数据寄存器。它们既能并行工作,又能交叉工作。
多体并行存储器分为高位交叉编址和低位交叉编址两种。
-
高位交叉编址(顺序方式)
高位地址表示体号,低位地址为体内地址。如图所示,存储器共有4个模块M0~M3,每个模块有n个单元,各模块的地址范围如图中所示。
特点:
- 高位交叉方式下,总是把低位的体内地址送到由高位体号确定的模块内进行译码。
- 顺序串行存取。访问一个连续主存块时,总是先在一个模块内访问,等到该模块访问完才转到下一个模块访问,CPU总是按顺序访问存储模块,各模块不能被并行访问,因而不能提高存储器的吞吐率。
-
低位交叉编址(交叉方式)
低位地址为体号,高位地址为体内地址。
每个模块按“模m”交叉编址,模块号=单元地址%m,假定有m个模块,每个模块有k个单元,则0,m,…,(k-1)m单元位于M0;第1,m+1,…,(k-1)m+1单元位于M1;以此类推。
特点:
- 低位交叉方式下,总是把高位的体内地址送到由低位体号确定的模块内进行译码。
- 程序连续存放在相邻模块中,因此称采用此编址方式的存储器为交叉存储器。
- 采用低位交叉编址后,可在不改变每个模块存取周期的前提下,采用流水线的方式并行存取,提高存储器的带宽。
设模块字长等于数据总线宽度,模块存取一个字的存取周期为T,总线传送周期为r,为实现流水线方式存取,存储器交叉模块数应大于等于
m = T / r m=T/r m=T/r
式中,m称为交叉存取度。每经过时间延迟后启动下一个模块,交叉存储器要求其模块数必须大于等于m,以保证启动某模块后经过m×r的时间后再次启动该模块时,其上次的存取操作已经完成(即流水线不间断)。这样,连续存取m个字所需的时间为
t 1 = T + ( m − 1 ) r t_1=T+(m-1)r t1=T+(m−1)r
而顺序方式连续读取m个字所需的时间为 t 2 = m T t_2=mT t2=mT。可见低位交叉存储器的带宽大大提高。【例】设存储器容量为32个字,字长为64位,模块数m=4,分别采用顺序方式和交叉方式进行组织。存储周期T=200ns,数据总线宽度为64位,总线传输周期r=50ns。在连续读出4个字的情况下,求顺序存储器和交叉存储器各自的带宽。
解:顺序存储和交叉存储器连续读出m=4个字的的信息总量为
q = 64 位 × 4 = 256 位 q=64位×4=256位 q=64位×4=256位
顺序存储器和交叉存储器连续读出4个字所需时间为
t 1 = m T = 4 × 200 n s = 800 n s = 8 × 1 0 − 7 s t 2 = T + ( m − 1 ) r = 200 n s + 3 × 50 n s = 350 n s = 3.5 × 1 0 − 7 s t_1=mT=4×200ns=800ns=8×10^{-7}s\\ t_2=T+(m-1)r=200ns+3×50ns=350ns=3.5×10^{-7}s t1=mT=4×200ns=800ns=8×10−7st2=T+(m−1)r=200ns+3×50ns=350ns=3.5×10−7s
顺序存储器和交叉存储器的带宽分别是
W 1 = q / t 1 = 256 / ( 8 × 1 0 − 7 ) = 3.2 × 1 0 8 b / s W 2 = q / t 2 = 256 / ( 3.5 × 1 0 − 7 ) = 7.3 × 1 0 8 b / s W_1=q/t_1=256/(8×10^{-7})=3.2×10^8b/s\\ W_2=q/t_2=256/(3.5×10^{-7})=7.3×10^8b/s W1=q/t1=256/(8×10−7)=3.2×108b/sW2=q/t2=256/(3.5×10−7)=7.3×108b/s
-
3.3 主存储器与CPU的连接
3.3.1 连接原理
单个芯片的容量不可能很大,往往通过存储器芯片扩展技术,将多个芯片集成在一个内存条上,然后由多个内存条及主板上的ROM芯片组成计算机所需的主存空间,再通过总线与CPU相连。下图是存储控制器、存储器总线和内存条的连接关系示意图。
内存条插槽就是存储器总线,内存条中的信息通过内存条的引脚,再通过插槽内的引线连接到主板上,通过主板上的导线连接到CPU芯片。
主存与CPU连接原理:
- 1)主存储器通过数据总线、地址总线和控制总线与CPU连接。
- 2)数据总线的位数与工作频率的乘积正比于数据传输率。
- 3)地址总线的位数决定了可寻址的最大内存空间。
- 4)控制总线(读/写)指出总线周期的类型和本次输入/输出操作完成的时刻。
3.3.2 主存容量的扩展
-
位扩展法
用多个存储器件对字长进行扩充,增加存储字长使其数据位数与CPU的数据线数相等。
连接方式:将多个存储芯片的地址端、片选端和读写控制端相应并联,数据端分别引出。
注意:仅采用位扩展时,各芯片连接地址线的方式相同,但连接数据线的方式不同,在某一时刻选中所有的芯片,所以片选信号CS要连接到所有芯片。
-
字扩展法
增加存储器中字的数量,而位数不变。
连接方式:将芯片的地址线、数据线、读写控制线相应并联,而由片选信号来区分各芯片的地址范围。
如上图所示,用4片16K×8位的RAM芯片组成64K×8位的存储器。将 A 15 A 14 A_{15}A_{14} A15A14作为片选信号,连接2/4译码器,完成对4片RAM芯片的选择。各芯片的地址分配如下:
- 第1片,最低地址:0000000000000000;最高地址:0011111111111111(16位)
- 第2片,最低地址:0100000000000000;最高地址:0111111111111111
- 第3片,最低地址:1000000000000000;最高地址:1011111111111111
- 第4片,最低地址:1100000000000000;最高地址:1111111111111111
注意:仅采用字扩展时,各芯片连接地址线的方式相同,连接数据线的方式也相同,但在某一时刻只需选中部分芯片,所以通过片选信号CS或采用译码器设计连接到相应的芯片。
-
字位同时扩展法
字位同时扩展是指既增加存储字的数量,又增加存储字长。
如上图所示,用8片16K×4位的RAM芯片组成64K×8位的存储器。每两片构成一组16K×8位的存储器(位扩展),4组便构成64K×8位的存储器(字扩展)。
注意:采用字位同时扩展时,各芯片连接地址线的方式相同,但连接数据线的方式不同,而且需要通过片选信号CS或采用译码器设计连接到相应的芯片。
3.3.3 存储芯片的地址分配和片选
CPU要实现对存储单元的访问,首先要选择存储芯片,即进行片选;然后为选中的芯片依地址码选择相应的存储单元,以进行数据的存取,即进行字选。
片内的字选通常是由CPU送出的N条低位地址线完成的,地址线直接接到所有存储芯片的地址输入端(N由片内存储容量2n决定)。片选信号的产生分为线选法和译码片选法。
-
线选法
线选法用除片内寻址外的高位地址线直接(或经反相器)分别接至各个存储芯片的片选端,当某地址线信息为“0”时,就选中与之对应的存储芯片。这些片选地址线每次寻址时只能有一位有效,不允许同时有多位有效,这样才能保证每次只选中一个芯片。
假设4片2K×8位存储芯片用线选法构成8K×8位存储器,各芯片的片选信号见表,其中低位地址线A10~A0作为字选线,用于片内寻址。
- 优点:不需要地址译码器,线路简单。
- 缺点:地址空间不连续,选片的地址线必须分时为低电平(否则不能工作),不能充分利用系统的存储器空间,造成地址资源的浪费。
-
译码片选法
译码片选法用除片内寻址外的高位地址线通过地址译码器芯片产生片选信号。如上一节采用2/4译码器来实现字扩展。仅用2位便可以产生4位片选信号。
3.4 外部存储器
3.4.1 磁盘存储器
优点:①存储容量大,位价格低;②记录介质可重复使用:③记录信息可长期保存而不丢失,甚至可脱机存档④非破坏性读出,读出时不需要再生。
缺点:存取速度慢,机械结构复杂,对工作环境要求较高。
-
磁盘设备的组成
- 硬盘存储器的组成:硬盘存储器由磁盘驱动器、磁盘控制器和盘片组成。
- 磁盘驱动器。核心部件是磁头组件和盘片组件,温彻斯特盘是一种可移动磁头固定盘片的硬盘存储器。
- 磁盘控制器。硬盘存储器和主机的接口,主流的标准有 IDE、SCSI、SATA等。
-
存储区域:一块硬盘含有若干记录面,每个记录面划分为若干磁道,而每条磁道又划分为若干扇区,扇区(也称块)是磁盘读写的最小单位,即磁盘按块存取。
- 磁头数(Heads):即记录面数,表示硬盘共有多少个磁头,磁头用于读取/写入盘片上记录面的信息,一个记录面对应一个磁头。
- 柱面数(Cylinders):表示硬盘每面盘片上有多少条磁道。在一个盘组中,不同记录面的相同编号(位置)的诸磁道构成一个圆柱面。
- 扇区数(Sectors):表示每条磁道上有多少个扇区。
- 硬盘存储器的组成:硬盘存储器由磁盘驱动器、磁盘控制器和盘片组成。
-
磁记录原理
-
原理:磁头和磁性记录介质相对运动时,通过电磁转换完成读/写操作。
-
编码方法:按某种方案(规律),把一连串的二进制信息变换成存储介质磁层中一个磁化翻转状态的序列,并使读/写控制电路容易、可靠地实现转换。
-
磁记录方式:通常采用调频制(FM)和改进型调频制(MFM)的记录方式。
-
-
磁盘的性能指标
-
记录密度。记录密度是指盘片单位面积上记录的二进制信息量,通常以道密度、位密度和面密度表示。
- 道密度是沿磁盘半径方向单位长度上的磁道数,
- 位密度是磁道单位长度上能记录的二进制代码位数,
- 面密度是位密度和道密度的乘积。
注意:磁盘所有磁道记录的信息量一定是相等的,并不是圆越大信息越多,故每个磁道的位密度都不同。
-
磁盘的容量。磁盘容量有非格式化容量和格式化容量之分。
- 非格式化容量是指磁记录表面可利用的磁化单元总数,它由道密度和位密度计算而来;
- 格式化容量是指按照某种特定的记录格式所能存储信息的总量。格式化后的容量比非格式化容量要小。
-
平均存取时间
平均存取时间 = 寻道时间(磁头移动到目的磁道) + 旋转延迟时间(磁头定位到所在扇区) + 传输时间(传输数据所花费的时间) + 平均存取时间=寻道时间(磁头移动到目的磁道)+\\旋转延迟时间(磁头定位到所在扇区)+\\传输时间(传输数据所花费的时间)+ 平均存取时间=寻道时间(磁头移动到目的磁道)+旋转延迟时间(磁头定位到所在扇区)+传输时间(传输数据所花费的时间)+
由于寻道和找扇区的距离远近不一,故寻道时间和旋转延退时间通常取平均值。
-
数据传输率。磁盘存储器在单位时间内向主机传送数据的字节数,称为数据传输率。假设磁盘转数为r转/秒,每条磁道容量为N字节,则数据传输率为
D r = r N D_r=rN Dr=rN
-
-
磁盘地址
主机向磁盘控制器发送寻址信息,磁盘的地址一般如图所示。
- 驱动器号:电脑可能有多个硬盘
- 柱面(磁道)号:移动磁头臂(寻道)
- 盘面号:激活某个磁头
- 扇区号:通过旋转将特定扇区划过磁头下方
若系统中有4=22个驱动器,每个驱动器带一个磁盘,每个磁盘256=28个磁道、16=24个盘面,每个盘面划分为16=24个扇区,则每个扇区地址要18位二进制代码,其格式如上图所示。
-
硬盘的工作过程
硬盘的主要操作是寻址、读盘、写盘。每个操作都对应一个控制字,硬盘工作时,第一步是取控制字,第二步是执行控制字。
硬盘属于机械式部件,其读写操作是串行的,不可能在同一时刻既读又写,也不可能在同一时刻读两组数据或写两组数据。
3.4.2 磁盘阵列
**RAID(独立余磁盘阵列)**是指将多个独立的物理磁盘组成一个独立的逻辑盘,数据在多个物理盘上分割交叉存储、并行访问,具有更好的存储性能、可靠性和安全性。
RAID的分级如下所示。在RAID1~RAID5几种方案中,无论何时有磁盘损坏,都可随时拔出受损的磁盘再插入好的磁盘,而数据不会损坏,提升了系统的可靠性。
-
RAID0:无冗余和无校验的磁盘阵列。
逻辑上相邻的两个扇区在物理上存到两个磁盘,类比“低位交叉编址的多体存储器”
RAID0把连续多个数据块交替地存放在不同物理磁盘的扇区中,几个磁盘交叉并行读写,不仅扩大了存储容量,而且提高了磁盘数据存取速度,但RAID0没有容错能力
-
RAID1:镜像磁盘阵列。
很粗暴,存两份数据。
RAID1是为了提高可靠性,使两个磁盘同时进行读写,互为备份,如果一个磁盘出现故障,可从另一磁盘中读出数据。两个磁盘当一个磁盘使用,意味着容量减少一半。
-
RAID2:采用纠错的海明码的磁盘阵列。
逻辑上连续的几个bit物理上分散存储在各个盘中;4bit信息位+3bit海明校验位——可纠正一位错
-
RAID3:位交叉奇偶校验的磁盘阵列。
-
RAID4:块交叉奇偶校验的磁盘阵列。
-
RAID5:无独立校验的奇偶校验磁盘阵列。
RAID通过同时使用多个磁盘,提高了传输率;通过在多个磁盘上并行存取来大幅提高存储系统的数据吞吐量;通过镜像功能,提高安全可靠性;通过数据校验,提供容错能力。
3.4.2 固态硬盘
-
原理
固态硬盘(SSD)是一种基于闪存技术的存储器,属于电可擦除ROM,即EEPROM。
-
组成
一个SSD由一个或多个闪存芯片和闪存翻译层组成。
- 闪存芯片:替代传统旋转磁盘中的机械驱动器,每个芯片包含多个块(block),每个块包含多个页(page)
- 闪存翻译层:将来自CPU的逻辑块读写请求翻译成对底层物理设备的读写控制信号,负责翻译逻辑块号,找到对应页(Page)
-
读写性能特性
- 以页(page)为单位读/写——相当于磁盘的“扇区"
- 以块(block)为单位"擦除",擦干净的块,其中的每页都可以写一次,读无限次
- 支持随机访问,系统给定一个逻辑地址,闪存翻译层可通过电路迅速定位到对应的物理地址
- 读快、写慢。要写的页如果有数据,则不能写入,需要将块内其他页全部复制到一个新的(擦除过的)块中,再写入新的页。
-
与机械硬盘相比的特点
- SSD读写速度快,随机访问性能高,用电路控制访问位置;机械硬盘通过移动磁臂旋转磁盘控制访问位置,有寻道时间和旋转延迟
- SSD安静无噪音、耐摔抗震、能耗低、造价更贵
- SSD的一个“块"被擦除次数过多(重复写同一个块)可能会坏掉,而机械硬盘的扇区不会因为写的次数太多而坏掉
-
磨损均衡技术
思想:将“擦除"平均分布在各个块上,以提升使用寿命
- 动态磨损均衡:写入数据时,优先选择累计擦除次数少的新闪存块、
- 静态磨损均衡:SSD监测并自动进行数据分配、迁移,让老旧的闪存块承担以读为主的储存任务,让较新的闪存块承担更多的写任务
3.5 高速缓冲存储器
由于程序的转移概率不会很低,数据分布的离散性较大,所以单纯依靠并行主存系统提高主存系统的频宽是有限的。这就必须从系统结构上进行改进,即采用存储体系。
通常将存储系统分为“Cache-主存”层次和“主存-辅存”层次。
3.5.1 程序访问的局部性原理
-
空间局部性
在最近的未来要用到的信息(指令和数据),很可能与现在正在使用的信息在存储空间上是邻近的。因为指令通常是顺序存放、 顺序执行的,数据一般也是以向量、数组等形式簇聚地存储在一起的。
-
时间局部性
在最近的未来要用到的信息,很可能是现在正在使用的信息;因为程序中存在循环。
高速缓冲技术就是利用局部性原理,把程序中正在使用的部分数据存放在一个高速的、容量较小的Cache 中,使CPU的访存操作大多数针对Cache进行,从而提高程序的执行速度。
例:假定数组元素按行优先方式存储,对于下面的两个函数:
1)对于数组a的访问,哪个空间局部性更好?哪个时间局部性更好?
A程序的访问数组a的顺序为a[0][0], a[0][1]…, a[0][N-1];a[1][0], a[1][1]…;访问顺序与存放顺序一致,空间局部性好。
B程序的访问数组a的顺序为a[0][0], a[1][0]…, a[M-1][0];a[0][1], a[1][1]…;访问顺序与存放顺序不一致,每次访问都要跳过N个数组元素,即4N个字节,若主存与Cache的交换单位小于4N,则每次访问都要重装Cache,因而没有空间局部性。
两个程序时间局部性都差,因为每个数组元素都只被访问1次。
2)对于指令访问来说,for循环体的空间局部性和时间局部性如何?
对于for循环体,程序A和B中访问局部性相同。因为循环体内指令按序连续存放,所以空间局部性好;内部循环体指令被重复执行,因此时间局部性好。
3.5.2 Cache 的基本工作原理
Cache位于存储器层次结构的顶层,通常由SRAM构成,其基本结构如图所示。
-
Cache特点
-
Cache块:Cache和主存都被划分为相等的块,Cache块又称Cache行,每块由若干字节组成,块的长度称为块长(Cache行长)。
由于Cache的容量远小于主存的容量,所以Cache中的块数要远少于主存中的块数,它仅保存主存中最活跃的若干块的副本。
-
Cache按照某种策略,预测CPU在未来一段时间内欲访存的数据,将其装入Cache。
-
-
Cache工作流程
- 当CPU发出读请求时,若访存地址在Cache中命中,就将此地址转换成Cache地址,直接对Cache进行读操作,与主存无关;
- 若Cache不命中,则仍需访问主存,并把此字所在的块一次性地从主存调入Cache。(地址映射)
- 若此时Cache已满,则需根据某种替换算法,用这个块替换Cache中原来的某块信息。(替换算法)
注意:某些计算机中也采用同时访问Cache和主存的方式,若Cache命中,则主存访问终止;否则访问主存并替换Cache
整个过程全部由硬件实现。值得注意的是,CPU与Cache之间的数据交换以字为单位,而Cache与主存之间的数据交换则以Cache块为单位。
-
Cache性能分析
-
命中率:CPU欲访问的信息已在Cache中的比率称为Cache的命中率。
设一个程序执行期间,Cache的总命中次数为 N c N_c Nc,访问主存的总次数为 N m N_m Nm,则命中率 H H H为
H = N c / ( N c + N m ) H=N_c/(N_c+N_m) H=Nc/(Nc+Nm)
可见为提高访问效率,命中率H越接近1越好。 -
平均访问时间:设 t c t_c tc为命中时的Cache访问时间, t m t_m tm为未命中时的访问时间, 1 − H 1-H 1−H表示未命中率,则Cache-主存系统的平均访问时间 T a T_a Ta为
T a = H t c + ( 1 − H ) t m T_a=Ht_c+(1-H)t_m Ta=Htc+(1−H)tm
根据Cache的读、写流程,实现Cache时需解决以下关键问题:
- 1)数据查找。如何快速判断数据是否在 Cache 中。
- 2)地址映射。主存块如何存放在 Cache 中,如何将主存地址转换为Cache 地址。
- 3)替换策略。Cache满后,使用何种策略对Cache块进行替换或淘汰。
- 4)写入策略。如何既保证主存块和Cache 块的数据一致性,又尽量提升效率。
例:假设Cache的速度是主存的5倍,且Cache的命中率为95%,则采用Cache后,存储器性能提高多少(设Cache和主存同时被访问,若Cache命中则中断访问主存)?
解:设Cache存取周期为t,主存存取周期为5t,使用Cache的平均访问时间为:
T a = 95 % × t + ( 1 − 95 % ) × 5 t = 1.2 t T_a=95\%×t+(1-95\%)×5t=1.2t Ta=95%×t+(1−95%)×5t=1.2t
因此,采用Cache后,性能提升至5t/1.2t≈4.17倍 -
3.5.3 Cache和主存的映射方式
Cache 行中的信息是主存中某个块的副本,地址映射是指把主存地址空间映射到Cache地址空间,即把存放在主存中的信息按照某种规则装入Cache。
由于Cache行数比主存块数少得多,因此主存中只有一部分块的信息可放在Cache中,因此在Cache中要为每块加一个标记,指明它是主存中哪一块的副本。该标记的内容相当于主存中块的编号。为了说明Cache行中的信息是否有效,每个Cache行需要一个有效位。
-
全相联映射
主存中的每一块可以装入Cache中的任何位置,每行的标记用于指出该行取自主存的哪一块,所以CPU访存时需要与所有Cache行的标记进行比较。
-
优点:比较灵活,Cache块的冲突概率低,空间利用率高,命中率也高
-
缺点:标记的比较速度较慢,实现成本较高,通常需采用昂贵的按内容寻址的相联存储器进行地址映射。
全相联映射的地址结构为
-
-
直接映射
主存块只能放到特定的某个Cache行,若这个位置已有内容,则产生冲突,原来的块被替换(无需替换算法)
直接映射的关系可定义为:
C a c h e 行号 = 主存块号 % C a c h e 总行数 Cache行号=主存块号\%Cache总行数 Cache行号=主存块号%Cache总行数
假设Cache有2c行,主存有2m块,在直接映射方式,主存的第0块、第2c块、第2c+1块…只能映射到第0行
由此看出,主存块号低c位正好是要装入Cache的行号。给每个Cache设置长为t=m-c的标记(tag),当主存某块调入Cache后,就将其块号的高t位设置在对应Cache行的标记中,如图(a)所示。
直接映射的地址结构为:
CPU访存过程如图(b)所示,
-
首先根据访存地址中间的c位,找到对应的Cache行,将对应Cache行中的标记和主存地址的高t位标记进行比较,若相等且有效位为1,则访问Cache“命中”,此时根据主存地址中低位的块内地址,在对应的Cache行中存取信息;
-
若不相等或有效位为0,则“不命中”,此时CPU从主存中读出该地址所在的一块信息送到对应的Cache行中,将有效位置1,并将标记设置为地址中的高t位,同时将该地址中的内容送CPU。
-
-
组相联映射
主存块可以放到特定分组中的任意位置。常用的有2路组相联映射,如下图所示。
组相联映射的关系可以定义为
C a c h e 组号 = 主存块号 % C a c h e 组数( Q ) Cache组号=主存块号\%Cache组数(Q) Cache组号=主存块号%Cache组数(Q)
路数越大,即每组Cache行的数量越大,发生块冲突的概率越低,但相联比较电路也越复杂。选定适当的数量,可使组相联映射的成本接近直接映射,而性能上仍接近全相联映射。组相联映射的地址结构为:
CPU访存过程如下:
- 首先根据访存地址中间的组号找到对应的Cache组;
- 将对应Cache组中每个行的标记与主存地址的高位标记进行比较;
- 若有一个相等且有效位为1,则访问Cache命中,此时根据主存地址中的块内地址,在对应Cache行中存取信息;
- 若都不相等或虽相等但有效位为0,则不命中,此时CPU从主存中读出该地址所在的一块信息送到对应Cache组的任意一个空闲行中,将有效位置1,并设置标记,同时将该地址中的内容送CPU。
3.5.4 Cache中主存块的替换算法
全相联映射和组相联映射需要,直接相连映射不需要。从主存向Cache传送一个新块,当Cache或Cache组中的空间已被占满时,就需要使用替换算法置换Cache行。而
-
随机算法(RAND)
-
算法:若Cache已满,则随机选择一块替换。
-
特点:实现简单,但完全没考虑局部性原理,命中率低,(实际效果很不稳定)
-
-
先进先出算法(FIFO)
-
算法:若Cache已满,则替换最先被调入Cache的块
-
特点:FIFO依然没考虑局部性原理,最先被调入Cache的块也有可能是被频繁访问的
-
-
近期最少使用(LRU)
-
算法:为每一个Cache块设置一个“计数器”,用于记录每个Cache块已经有多久没被访问了。当Cache满后替换“计数器”最大的
- ①命中时,所命中的行的计数器清零,比其低的计数器加1,其余不变;
- ②未命中且还有空闲行时,新装入的行的计数器置0,其余非空闲行全加1;
- ③未命中且无空闲行时,计数值最大的行的信息块被淘汰,新装行的块的计数器置0,其余全加1。
Cache块的总数=2n,则计数器只需n位。且Cache装满后所有计数器的值定不重复
-
特点:基于“局部性原理”,近期被访问过的主存块,在不久的将来也很有可能被再次访问,因此淘汰最久没被访问过的块是合理的。LRU算法的实际运行效果优秀,Cache命中率高。
若被频繁访问的主存块数量>Cache行的数量,则有可能发生“抖动”,如:[1,2,3,4,5,1,2,3,4,5,1,2…)
假定采用四路组相联映射,有5个主存块{1,2,3,4,5}映射到Cache的同一组,对于主存访问{1,2,3,4,1,2,5,1,2,3,4,5},采用LRU算法的替换过程如图。
-
-
最近不经常使用(LFU)
-
算法:为每一个Cache块设置一个“计数器”,用于记录每个Cache块被访问过几次。当Cache满后替换“计数器”最小的。
-
新调入的块计数器=0,之后每被访问一次计数器+1。需要替换时,选择计数器最小的一行
-
若有多个计数器最小的行,可按行号递增或FIFO策略进行选择
-
-
特点:曾经被经常访问的主存块在未来不一定会用到(如:微信视频聊天相关的块),并没有很好地遵循局部性原理,因此实际运行效果不如LRU
-
3.5.5 Cache写策略
因为Cache中的内容是主存块副本,当对Cache中的内容进行更新时,就需选用写操作策略使Cache内容和主存内容保持一致。此时分两种情况。
-
写命中
- 写回法:当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此块被换出时才写回主存
-
减少了访存次数,但存在数据不一致的隐患。
-
每个Cache行必须设直一个标志位(脏位),以反映此块是否被CPU修改过。
-
全写法:当CPU对Cache写命中时,必须把数据同时写入Cache和主存,一般使用写缓冲(write buffer)
- 访存次数增加,速度变慢,但更能保证数据一致性
-
写不命中
- 写分配法:当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改。
- 通常搭配写回法使用。
- 非写分配法:当CPU对Cache写不命中时,只写入主存,不调入Cache。
- 搭配全写法使用。
- 只有“读”未命中时才调入Cache
- 写分配法:当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改。
-
多级Cache
现代计算机常采用多级Cache离CPU越近的速度越快,容量越小离CPU越远的速度越慢,容量越大。
-
各级Cache之间常采用**“全写法+非写分配法”**
-
Cache-主存 之间常采用**“写回法+写分配法”**
-
3.6 虚拟存储
主存和辅存共同构成了虚拟存储器,二者在硬件和系统软件的共同管理下工作。对于应用程序员而言,虚拟存储器是透明的。虚拟存储器具有主存的速度和辅存的容量。
3.6.1 虚拟存储器的基本概念
虚拟存储器将主存或辅存的地址空间统一编址,形成一个庞大的地址空间,在这个空间内,用户可以自由编程,而不必在乎实际的主存容量和程序在主存中实际的存放位置。
-
地址空间
-
逻辑地址:又称虚地址,用户编程允许涉及的地址。虚地址要比实地址大很多。
-
程序空间:又称虚拟空间,虚地址对应的存储空间。虚拟存储器的地址空间如下图所示。
-
物理地址:又称实地址,实际的主存单元地址。
-
主地址空间:又称实地址空间,实地址对应的存储空间。
-
-
虚拟地址工作流程
CPU使用虚地址时,由辅助硬件找出虚地址和实地址之间的对应关系,并判断这个虚地址对应的存储单元内容是否已装入主存。
- 若已在主存中,则通过地址变换,CPU可直接访问主存指示的实际单元;
- 若不在主存中,则把包含这个字的一页或一段调入主存后再由CPU访问。
- 若主存已满,则采用替换算法置换主存中的交换块(即页面)。
-
映射方式与写机制
虚拟存储机制采用全相联映射,每个虚页面可以存放到对应主存区域的任何一个空闲页位置。
当进行写操作时,不能每次写操作都同时写回磁盘,因而,在处理一致性问题时,采用回写法。
3.6.2 页式虚拟存储器
页式虚拟存储器以页为基本单位。虚拟空间与主存空间都被划分成同样大小的页。
-
概念
- 实页:主存的页,又称页框。
- 虚页:虚存的页。
- 虚拟地址:虚页号+页内地址。
- 页表:页表是一张存放在主存中的虚页号和实页号的对照表,它记录程序的虚页调入主存时被安排在主存中的位置。页表一般长久地保存在内存中。虚拟地址到物理地址的转换是由页表实现的。
-
页表
下图为主存中页表示例。
- 有效位:又称装入位,用来表示对应页面是否在主存,
- 若为1,则表示该虚拟页已从外存调入主存,此时页表项存放该页的物理页号;
- 若为0,则表示没有调入主存,此时页表项可以存放该页的磁盘地址。
- 脏位:又称修改位,用来表示页面是否被修改过,虚存机制中采用回写策略,利用脏位可判断替换时是否需要写回磁盘。
- 引用位:又称使用位,用来配合替换策略进行设置,例如是否实现最先调入(FIFO位)或最近最少用(LRU位)策略等。
页表的使用:
-
CPU执行指令时,需要先将虚拟地址转换为主存物理地址。下图为页表地址转换过程。
-
页表基址寄存器存放进程的页表首地址,然后根据虚拟地址高位部分的虚拟页号找到对应的页表项,
- 若装入位为1,则取出物理页号,和虚拟地址低位部分的页内地址拼接,形成实际物理地址;
- 若装入位为0,则说明缺页,需要操作系统进行缺页处理。
- 有效位:又称装入位,用来表示对应页面是否在主存,
-
快表(TLB)
-
问题:由地址转换过程可知,访存时先访问一次主存去查页表,再访问主存才能取得数据。如果缺页,那么还要进行页面替换、页面修改等,因此采用虚拟存储机制后,访问主存的次数更多了。
-
解决:将近期访问的页表项放入更高速的存储器组成的快表(TLB),可加快地址变换的速度。相应的把放在主存中的页表称为慢表。在地址转换时,首先查找快表,若命中,则无须访问主存中的页表。
-
结构:快表通常采用全相联或组相联方式。每个TLB项由页表表项内容加上一个TLB标记字段组成,
- TLB标记用来表示该表项取自页表中哪个虚页号对应的页表项,
- 全相联方式:TLB标记对应该页表项的虚页号;
- 组相联方式:TLB标记对应虚页号的高位部分,而虚页号的低位部分用于选择TLB组的组索引。
注意区别:快表中存储的是页表项的副本;Cache中存储的是主存块的副本
-
-
具有TLB和Cache的多级存储系统
下图为一个具有TLB和Cache的多级存储系统,其中Cache采用二路组相联方式。CPU给出一个32位的虚拟地址,TLB采用全相联方式。
-
CPU利用虚页号查询快表TLB。TLB每一项都有一个比较器,查找时将虚页号与每个TLB标记字段同时进行比较,
- 若有某一项相等且对应有效位为1,则TLB命中,此时可直接通过TLB进行地址转换;
- 若未命中,则TLB缺失,需要访问主存去查页表。
地址转换指,将虚拟地址转换为物理地址
-
TLB未命中查询页表(慢表)。图中所示的是两级页表方式,虚页号被分成页目录索引和页表索引两部分,由这两部分得到对应的页表项,从而进行地址转换,并将相应表项调入TLB,
- 若TLB已满,则还需要采用替换策略。
-
根据物理地址查询Cache。完成由虚拟地址到物理地址的转换后,Cache机构根据映射方式将物理地址划分成多个字段,然后根据映射规则找到对应的Cache行或组,
- 将对应Cache行中的标记与物理地址中的高位部分进行比较,若相等且对应有效位为1,则Cache命中,此时根据块内地址取出对应的字送CPU。
查找时,快表和慢表也可以同步进行,若快表中有此虚页号,则能很快地找到对应的实页号,并使慢表的查找作废,从而就能做到虽采用虚拟存储器但访问主存速度几乎没有下降。
在一个具有Cache和TLB的虚拟存储系统中,CPU一次访存操作可能涉及TLB、页表、Cache、主存和磁盘的访问,访问过程如下图所示。
可见,CPU访存过程中存在三种缺失情况:
- ①TLB缺失:要访问的页面的页表项不在TLB中;
- ②Cache缺失:要访问的主存块不在Cache中;
- ③Page缺失:要访问的页面不在主存中。这三种缺失的可能组合情况如下表所示。
- 最好的情况是第1种组合,此时无须访问主存;
- 第2种和第3种组合都需要访问一次主存;
- 第4种组合需要访问两次主存;
- 第5种组合发生“缺页异常",需要访问磁盘,并且至少访问两次主存。Cache缺失处理由硬件完成;
缺页处理由软件完成,操作系统通过“缺页异常处理程序”来实现;
而TLB缺失既可以用硬件又可以用软件来处理。
-
3.6.3 段式虚拟存储器
段式虚拟存储器中的段是==按程序的逻辑结构(功能模块)==划分的,各个段的长度因程序而异。
-
虚拟地址
虚拟地址=段号+段内地址
-
段表:是程序的逻辑段和在主存中存放位置的对照表,实现虚拟地址到实地址之间的变换。
段表的每行记录与某个段对应的段号、装入位、段起点和段长等信息。由于段的长度可变,所以段表中要给出各段的起始地址与段的长度。
-
访存方式
- CPU根据虚拟地址访存时,首先根据段号与段表基地址拼接成对应的段表行,
- 然后根据该段表行的装入位判断该段是否已调入主存
- 装入位为“1",表示该段已调入主存;
- 装入位为“0",表示该段不在主存中。
- 已调入主存时,从段表读出该段在主存中的起始地址,与段内地址(偏移量)相加,得到对应的主存实地址。下图为段式虚拟存储器的地址变换过程。
-
特点
- 优点:段的分界与程序的自然分界相对应,因而具有逻辑独立性,使得它易于编译、管理、修改和保护,也便于多道程序的共享
- 缺点:因为段长度可变,分配空间不便,容易在段间留下碎片,不好利用,造成浪费。
3.6.4 段页式虚拟荐储器
-
定义
把程序按逻辑结构分段,每段再划分为固定大小的页,主存空间也划分为大小相等的页,程序对主存的调入、调出仍以页为基本传送单位,这样的虚拟存储器称为段页式虚拟存储器。
-
内存布局
在段页式虚拟存储器中,每个程序对应一个段表,每段对应一个页表,段的长度必须是页长的整数倍,段的起点必须是某一页的起点。
-
地址转换
虚地址分为段号、段内页号、页内地址三部分。
- CPU根据虚地址访存时,首先根据段号得到段表地址;
- 然后从段表中取出该段的页表起始地址,与虚地址段内页号合成,得到页表地址;
- 最后从页表中取出实页号,与页内地址拼接形成主存实地址。
-
特点
- 优点:兼具页式和段式虚拟存储器的优点,可以按段实现共享和保护。
- 缺点:在地址变换过程中需要两次查表,系统开销较大。
3.6.5 虚拟存储器与Cache的比较
-
相同点
- 1)最终目标都是为了提高系统性能,两者都有容量、速度、价格的梯度。
- 2)都把数据划分为小信息块,并作为基本的传递单位,虚存系统的信息块更大。
- 3)都有地址的映射、替换算法、更新策略等问题。
- 4)依据程序的局部性原理应用“快速缓存的思想”,将活跃的数据放在相对高速的部件中。
-
不同点
-
1)Cache主要解决系统速度,而虚拟存储器却是为了解决主存容量。
-
2)Cache全由硬件实现,是硬件存储器,对所有程序员透明;而虚拟存储器由OS和硬件共同实现,是逻辑上的存储器,对系统程序员不透明,但对应用程序员透明。
主存一辅存:实现虚拟存储系统,解决了主存容量不够的问题
Cache-主存:解决了主存与CPU速度不匹配的问题
-
3)对于不命中性能影响,因为CPU的速度约为Cache的10倍,主存的速度为硬盘的100倍以上,因此虚拟存储器系统不命中时对系统性能影响更大。
-
4)CPU与Cache和主存都建立了直接访问的通路,而辅存与CPU没有直接通路。也就是说在Cache不命中时主存能和CPU直接通信,同时将数据调入Cache;而虚拟存储器系统不命中时,只能先由硬盘调入主存,而不能直接和CPU通信。
-
4 指令系统
4.1 指令系统
**指令(机器指令)**是指示计算机执行某种操作的命令。
指令系统:一台计算机的所有指令的集合构成该机的指令系统,也称指令集。指令系统是指令集体系结构(ISA)中最核心的部分,ISA完整定义了软件和硬件之间的接口,是机器语言或汇编语言程序员所应熟悉的。
ISA规定的内容主要包括:指令格式,数据类型及格式,操作数的存放方式,程序可访问的寄存器个数、位数和编号,存储空间的大小和编址方式,寻址方式,指令执行过程的控制方式等。
4.1.1 指令的基本格式
一条指令就是机器语言的一个语句,它是一组有意义的二进制代码。一条指令通常包括操作码字段和地址码字段两部分:
-
操作码:操作码指出指令中该指令应该执行什么性质的操作以及具有何种功能。
- 操作码是识别指令、了解指令功能及区分操作数地址内容的组成和使用方法等的关键信息。
- 例如,指出是算术加运算还是算术减运算,是程序转移还是返回操作。
-
地址码:地址码给出被操作的信息(指令或数据)的地址。包括参加运算的一个或多个操作数所在的地址、运算结果的保存地址、程序的转移地址、被调用的子程序的入口地址等。
-
指令的长度:指一条指令中所包含的二进制代码的位数。
- 指令字长取决于操作码的长度、操作数地址码的长度和操作数地址的个数。
- 指令长度与机器字长没有固定的关系,它可以等于机器字长,也可以大于或小于机器字长。
- 通常,把指令长度等于机器字长的指令称为单字长指令,
- 指令长度等于半个机器字长的指令称为半字长指令,
- 指令长度等于两个机器字长的指令称为双字长指令。
-
定长指令字结构:在一个指令系统中,若所有指令的长度都是相等的,则称为定长指令字结构。
- 定字长指令的执行速度快,控制简单。
-
变长指令字结构:若各种指令的长度随指令功能而异,则称为变长指令字结构。然而,因为主存一般是按字节编址的,所以指令字长多为字节的整数倍。
根据指令中操作数地址码的数目的不同,可将指令分成以下几种格式。
-
零地址指令:只给出操作码OP,没有显式地址。
- 1)不需要操作数的指令,如空操作指令、停机指令、关中断指令等。
- 2)零地址的运算类指令仅用在堆栈计算机中。通常参与运算的两个操作数隐含地从栈顶和次栈顶弹出,送到运算器进行运算,运算结果再隐含地压入堆栈。
-
一地址指令
-
1)只有目的操作数的单操作数指令,按A1地址读取操作数,进行OP操作后,结果存回原地址。
- 指令含义:OP(A1)→A1
- 如加1、减1、取反、求补等。
-
2)隐含约定目的地址的双操作数指令,按指令地址A1可读取源操作数,指令可隐含约定另一个操作数由ACC(累加器)提供,运算结果也将存放在ACC中。
- 指令含义:(ACC)OP(A1)→ACC
- 若指令字长为32位,操作码占8位,1个地址码字段占24位,则指令操作数的直接寻址范围为224= 16M
注:A1指某个主存地址,(A1)表示A1所指向的地址中的内容
-
-
二地址指令
- 对于常用的算术和逻辑运算指令,往往要求使用两个操作数,需分别给出目的操作数和源操作数的地址,其中目的操作数地址还用于保存本次的运算结果。
- 指令含义:(A1)OP(A2)→A1
- 完成一条指令需要访存4次,取指→读A1→读A2→写A1
-
三地址指令
- 常用于需要两个操作数的算术运算、逻辑运算相关指令
- 指令含义:(A1)OP(A2)→A3
- 完成一条指令需要访存4次,取指→读A1→读A2→写A3
-
四地址指令
- 执行指令后,将PC的值修改位A4所指地址
- 指令含义:(A1)OP(A2)→A3,A4=下一条将要执行指令的地址。
- 完成一条指令需要访存4次,取指→读A1→读A2→写A3
n位地址码的直接寻址范围=2n,若指令总长度固定不变,则地址码数量越多,寻址能力越差
4.1.2 定长操作码指令格式
定长操作码指令在指令字的最高位部分分配固定的若干位(定长)表示操作码。
一般位操作码字段的指令系统最大能够表示2n条指令。定长操作码对于简化计算机硬件设计,提高指令译码和识别速度很有利。当计算机字长为32位或更长时,这是常规用法。
4.1.3 扩展操作码指令格式
为了在指令字长有限的前提下仍保持比较丰富的指令种类,可采取可变长度操作码,即全部指令的操作码字段的位数不固定,且分散地放在指令字的不同位置上。显然,这将增加指令译码和分析的难度,使控制器的设计复杂化。
-
设计方案
-
1)不允许短码是长码的前缀,即短操作码不能与长操作码的前面部分的代码和同。
-
2)各指令的操作码一定不能重复。
通常情况下,对使用频率较高的指令,分配较短的操作码;对使用频率较低的指令,分配较长的操作码,从而尽可能减少指令译码和分析的时间。
设地址长度为n,上一层留出m种状态,下一层可扩展出m×2n种状态。
-
-
对比
- 定长操作码
- 优:定长操作码对于简化计算机硬件设计,提高指令译码和识别速度很有利;
- 缺:指令数量增加时会占用更多固定位,留给表示操作数地址的位数受限。
- 扩展操作码
- 优:在指令字长有限的前提下仍保持比较丰富的指令种类;
- 缺:增加了指令译码和分析的难度,使控制器的设计复杂化。
- 定长操作码
4.1.4 指令的操作类型
设计指令系统时必须考虑应提供哪些操作类型,指令操作类型按功能可分为以下几种。
-
数据传送
- MOV:传送指令通常有寄存器之间的传送
- LOAD:从内存单元读取数据到CPU寄存器
- STORE:从CPU寄存器写数据到内存单元
-
算术和逻辑运算
- 算术:加、减、乘、除、增1、减1、求补、浮点运算、十进制运算
- 逻辑:与、或、非、异或、位操作、位测试、位清除、位求反
-
移位操作
- 算术移位、逻辑移位、循环移位(带进位和不带进位)
-
转移操作
-
无条件转移(JMP):无条件转移指令在任何情况下都执行转移操作
-
条件转移(JZ):结果为0;(JO):结果溢出;(JC):结果有进位
-
调用(CALL)和返回(RETURN)
调用指令和转移指令的区别:执行调用指令时必须保存下一条指令的地址(返回地址),当子程序执行结束时,根据返回地址返回到主程序继续执行;而转移指令则不返回执行。
-
陷阱(Trap)与陷阱指令
-
-
输入输出操作
- 成CPU与IO端口交换数据或传送控制命令及状态信息
4.2 指令的寻址方式
寻址方式是指寻找指令或操作数有效地址的方式,即确定本条指令的数据地址及下一条待执行指令的地址的方法。寻址方式分为指令寻址和数据寻址两大类。
4.2.1 指令寻址和数据寻址
寻址方式分为指令寻址和数据寻址两大类。寻找下一条将要执行的指令地址称为指令寻址;寻找本条指令的数据地址称为数据寻址。
-
指令寻址
指令寻址方式有两种:一种是顺序寻址方式,另一种是跳跃寻址方式。
- 顺序寻址:通过程序计数器PC加1(1个指令字长),自动形成下一条指令的地址。
- 跳跃寻址:通过转移类指令实现。执行转移类指令导致的PC值改变,跳跃的地址分为绝对地址(由标记符直接得到)和相对地址(相对于当前指令地址的偏移量)。
-
数据导址
数据寻址是指如何在指令中表示一个操作数的地址,如何用这种表示得到操作数或怎样计算出操作数的地址。
指令格式:
4.2.2 常见的数据寻址方式
-
隐含寻址
不是明显地给出操作数的地址,而是在指令中隐含着操作数的地址。
例,单地址指令不指出第二操作数的地址,而规定累加器(ACC)作为第二操作数地址,指令格式明显指出的仅是第一操作数的地址。累加器(ACC)对单地址指令格式是隐含地址。
-
优点:有利于缩短指令字长。
-
缺点:需增加存储操作数或隐含地址的硬件。
-
-
立即(数)寻址
形式地址A就是操作数本身,又称为立即数,一般采用补码形式。图中#表示立即寻址特征。
-
执行:取指令访存1次,执行指令访存0次
-
优点:执行指令阶段不访问主存,执行指令时间最短
-
缺点:A的位数限制了立即寻址的范围。如A的位数为n,且立即数采用补码时,可表示-2n-1~2n-1-1
-
-
直接寻址
指令字中的形式地址 A是操作数的真实地址EA,即EA=A。
- 执行:取指令访存1次、执行指令访存1次,暂不考虑存结果,共访存2次
- 优点:简单,指令执行阶段仅访问一次主存,不需专门计算操作数的地址。
- 缺点:A的位数决定了该指令操作数的寻址范围,操作数的地址不易修改
-
间接导址
指令的地址字段给出的形式地址不是操作数的真正地址,而是操作数有效地址所在的存储单元的地址,也就是操作数地址的地址,即EA=(A)。
主存字第一位为1时,表示取出的不是操作数地址,即多次间接寻址
主存字第一位为0时,表示取得的是操作所的地址
- 执行:取指令访存1次,执行指令访存2次,暂不考虑存结果,共访存3次,
- 优点:可扩大寻址范围(有效地址EA的位数大于形式地址A的位数)。便于编制程序(用间接寻址可以方便地完成子程序返回)。
- 缺点:指令在执行阶段要多次访存(一次间址需两次访存,多次寻址需根据存储字的最高位确定几次访存)。
-
寄存器寻址
在指令字中直接给出操作数所在的寄存器编号,即EA=Ri,其操作数在由Ri所指的寄存器内。
- 执行:取指令访存1次,执行指令访存0次,暂不考虑存结果,共访存1次
- 优点:指令在执行阶段不访问主存,只访问寄存器,指令字短且执行速度快,支持向量/矩阵运算。
- 缺点:寄存器价格昂贵,计算机中寄存器个数有限
-
寄存器间接寻址
寄存器Ri中给出的不是一个操作数,而是操作数所在主存单元的地址,即EA=(Ri)
- 执行:取指令访存1次,执行指令访存1次,暂不考虑存结果,共访存2次
- 特点:与一般间接寻址相比速度更快,但指令的执行阶段需要访问主存(因为操作数在主存中)。
-
相对寻址
把程序计数器PC的内容加上指令格式中的形式地址A而形成操作数的有效地址,即EA=(PC)+A,其中A是相对于PC所指地址的位移量,可正可负,补码表示。
当CPU从存储器中取出一字节时,会自动执行(PC)+1→PC。
当前指令存放地址=1000,若当前指令字长=2B,则PC+2;若当前指令字长=4B,则PC+4。因此取出当前指令后PC可能为1002 or 1004
- 优点:这段代码在程序内浮动时不用更改跳转指令的地址码。相对寻址广泛应用于转移指令。
-
基址寻址
将CPU中基址寄存器(BR)的内容加上指令格式中的形式地址A,而形成操作数的有效地址,即EA=(BR)+A
注:基址寄存器是面向操作系统的,其内容由操作系统或管理程序确定。在程序执行过程中,基址寄存器的内容不变(作为基地址),形式地址可变(作为偏移量)。
采用通用寄存器作为基址寄存器时,可由用户决定哪个寄存器作为基址寄存器,但其内容仍由操作系统确定。
- 优点:可扩大寻址范围(基址寄存器的位数大于形式地址A的位数);用户不必考虑自己的程序存于主存的哪个空间区域,因此有利于多道程序设计,并可用于编制浮动程序,但偏移量的位数较短。
-
变址寻址
有效地址EA等于指令字中的形式地址A与变址寄存器IX的内容相加之和,即EA=(IX)+A,其中Ix可为变址寄存器(专用),也可用通用寄存器作为变址寄存器
注:变址寄存器是面向用户的,在程序执行过程中,变址寄存器的内容可由用户改变(IX作为偏移量),形式地址A不变(作为基地址)
- 优点:在数组处理过程中,可设定A为数组的首地址,不断改变变址寄存器IX的内容,便可很容易形成数组中任一数据的地址,特别适合编制循环程序。
基址寻址和变址寻址区别
基址寻址面向系统,主要用于为多道程序或数据分配存储空间,因此基址寄存器的内容通常由操作系统或管理程序确定,在程序的执行过程中其值不可变,而指令字中的A是可变的;
变址寻址立足于用户,主要用于处理数组问题,在变址寻址中,变址寄存器的内容由用户设定,在程序执行过程中其值可变,而指令字中的A是不可变的。 -
堆栈寻址
操作数存放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。
堆栈是存储器(或专用寄存器组)中一块特定的按“后进先出(LIFO)”原则管理的存储区,该存储区中被读/写单元的地址是用一个特定的寄存器给出的,该寄存器称为堆栈指针(SP)。
寄存器堆栈又称硬堆栈。寄存器堆伐的成本较高,不适合做大容量的堆栈;而从主存中划出一段区域来做堆栈是最合算且最常用的方法,这种堆栈称为软堆栈。
堆栈可用于函数调用时保存咨前函数的相关信息,堆栈寻址大多数都是无操作数,因为操作数地址隐含使用SP,如POP和PUSH指令。
- 访存次数:硬堆栈不访存,软堆栈访存1次
下面简单总结寻址方式、有效地址及访存次数(不含取本条指令的访存)
寻址方式 | 有效地址 | 访存次数 |
---|---|---|
隐含寻址 | 程序指定 | 0 |
立即寻址 | A即是操作数 | 0 |
直接寻址 | EA=A | 1 |
一次间接寻址 | EA=(A) | 2 |
寄存器寻址 | EA=Ri | 0 |
寄存器间接一次寻址 | EA=(Ri) | 1 |
相对寻址 | EA=(PC)+A | 1 |
基址寻址 | EA=(BR)+A | 1 |
变址寻址 | EA=(IX)+A | 1 |
4.3 程序的机器级代码表示
4.3.1 常用汇编指令介绍
-
相关寄存器
x86处理器中有8个32位的通用寄存器,为了向后兼容,EAX、EBX、ECX和EDX的高两位字节和低两位字节可以独立使用,E为Extended,表示32位。
除EBP和ESP外,其他几个寄存器的用途是比较任意的。
-
汇编指令格式
使用不同的编程工具开发程序时,用到的汇编程序也不同,一般有两种不同的汇编格式:AT&T格式和Intel格式。
-
AT&T格式的指令只能用小写字母,而Intel格式的指令对大小写不敏感
-
在AT&T格式中,第一个为源操作数,第二个为目的操作数,方向从左到右,合乎自然;在Intel格式中,第一个为目的操作数,第二个为源操作数,方向从右向左
-
在AT&T格式中,寄存器需要加前缀“%”,立即数需要加前缀“$”;在Intel格式中,寄存器和立即数都不需要加前缀。
-
在内存寻址方面,AT&T格式使用“(”和“)“、而tel格式使用“[”和“]”。
-
在处理复杂寻址方式时,例如AT&T格式的内存操作数“disp(base,idex,scae)”分别表示偏移量、基址寄存器、变址寄存器和比例因子,如“8(%edx,%eax,2)”表示操作数为M[R[ed]+R[eax]*2+8],其对应的Intel格式的操作数为“[edx+eax*2+8]”
-
在指定数据长度方面,AT&T格式指令操作码的后面紧跟一个字符,表明操作数大小,"b"表示byte(字节)、“w”表示word(字)或“l”表示long(双字)。Intel格式也有类似的语法,它在操作码后面显式地注明byte ptr、word ptr或dword ptr。
由于32或64位体系结构都是由16位扩展而来的,因此用word (字)表示16位
下表展示两种格式的几条不同指令。
-
-
常用指令
汇编指令通常可以分为数据传送指令、逻辑计算指令和控制流指令,下面以Intel格式为例,介绍一些重要的指令。以下用于操作数的标记分别表示寄存器、内存和常数。
-
数据传送指令
-
mov 指令
将第二个操作数 (寄存器的内容、内存中的内容或常数值) 复制到第一个操作数(寄存器或内存)。但不能用于直接从内存复制到内存。
其语法如下:
mov <reg>,<reg> mov <reg>,<mem> mov <mem>,<reg> mov <reg>,<con> mov <mem>,<con>
举例:
mov eax,ebx #将ebx值复制到eax mov byte ptr [var],5 #将5保存到var值指示的内存地址的一字节中
-
push指令
将操作数压入内存的栈,常用于函数调用。ESP是栈顶,压栈前先将ESP值减4(栈增长方向与内存地址增长方向相反),然后将操作数压入ESP指示的地址。
其语法如下:
push <reg32> push <mem> push <con32>
举例(注意,栈中元素固定32位):
push eax #将eax值压栈 push [var] #将var值指示的内存地址的4字节值压栈
-
pop指令
与push指令相反,pop指令执行的是出栈工作,出栈前先将ESP指示的地址中的内容出栈,然后将ESP值加4。
其语法如下:
pop edi #弹出栈顶元素送到edi pop [ebx] #弹出栈顶元素送到ebx值指示的内存地址的4字节中
-
-
常见算数运算指令
除法运算中,s为除数,被除数被提取安排到edx:eax中
-
add/sub指令:add指令将两个操作数相加,相加的结果保存到第一个操作数中。sub指令用于两个操作数相减,相减的结果保存到第一个操作数中。
其语法如下:
add <reg>,<reg> / sub <reg>,<reg> add <reg>,<mem> / sub <reg>,<mem> add <mem>,<reg> / sub <mem>,<reg> add <reg>,<con> / sub <reg>,<con> add <mem>,<con> / sub <mem>,<con>
举例:
sub eax,10 #eax ← eax-10 add byte ptr [var],10 #10与var值指示的内存地址的一字节值相加,并将结果保存在原位置
-
inc/dec指令:inc、dec指令分别表示将操作数自加1、自减1。
其语法如下:
inc <reg> / dec <reg> inc <mem> / dec <mem>
举例:
dec eax #eax值自减1 inc dword ptr [var] #var值指示的内存地址的4字节值自加1
-
imul指令。带符号整数乘法指令,有两种格式:
- ①两个操作数,将两个操作数相乘,将结果保存在第一个操作数中,第一个操作数必须为寄存器;
- ②三个操作数,将第二个和第三个操作数相乘,将结果保存在第一个操作数中,第一个操作数必须为寄存器。
imul <reg32>,<reg32> imul <reg32>,<mem> imul <reg32>,<reg32>,<con> imul <reg32>,<mem>,<con>
举例:
imul eax,[var] #eax ← eax * [var] imul esi,edi,25 #esi ← edi * 25
-
idiv指令:带符号整数除法指令,它只有一个操作数,即除数,而被除数则为edx:eax中的内容(64位整数),操作结果有两部分:商和余数,商送到eax,余数则送到edx。
其语法如下:
idiv <reg32> idiv <mem>
举例:
idiv ebx idiv dword ptr [var]
-
-
常见逻辑运算指令
-
and/or/xor指令。and、or、xor指令分别是逻辑与、逻辑或、逻辑异或操作指令,用于操作数的位操作,操作结果放在第一个操作数中。
语法如下:
and <reg>,<reg> / or <reg>,<reg> / xor <reg>,<reg> and <reg>,<mem> / or <reg>,<mem> / xor <reg>,<mem> and <mem>,<reg> / or <mem>,<reg> / xor <mem>,<reg> and <reg>,<con> / or <reg>,<con> / xor <reg>,<con> and <mem>,<con> / or <mem>,<con> / xor <mem>,<con>
举例:
and eax,0fh #将eax中的前28位全部置为0,最后4位保持不变 xor edx,edx #置edx中的内容为0
-
not指令。位翻转指令,将操作数中的每一位翻转,即0→1、1→0。
语法如下:
not <reg> not <mem>
举例:
not byte ptr [var] #将var值指示的内存地址的一字节的所有位翻转
-
neg指令。取负指令。
语法如下:
neg <reg> neg <mem>
举例:
neg eax #eax ← -eax
-
shl/shr 指令。逻辑移位指令,shl为逻辑左移,shr 为逻辑右移,第一个操作数表示被操
作数,第二个操作数指示移位的位数。语法如下:
shl <reg>,<con8> / shr <reg>,<con8> shl <mem>,<con8> / shr <mem>,<con8> shl <reg>,<cl> / shr <reg>,<cl> shl <mem>,<cl> / shr <mem>,<cl>
举例:
shl eax,1 #将eax值左移1位 shr ebx,cl #将ebx值右移位(n为c1中的值)
-
-
控制流指令
x86处理器维持着一个指示当前执行指令的指令指针(IP),当一条指令执行后,此指针自动指向下一条指令。IP寄存器不能直接操作,但可以用控制流指令更新。
通常用**标签(label)**指示程序中的指令地址,在x86汇编代码中,可在任何指令前加入标签。例如,
mov esi,[ebp+8] Begin: xor ecx,ecx mov eax,[esi]
这样就用Begin指示了第二条指令,控制流指令通过标签就可以实现程序指的跳转。
-
jmp 指令。jmp 指令控制IP转移到label所指示的地址(从 label 中取出指令执行)。
语法如下:
jmp <label>
举例:
jmp begin #转跳到begin标记的指令执行
-
jcondition指令。条件转移指令,依据CPU状态字中的一系列条件状态转移。CPU状态字中包括指示最后一个算术运算结果是否为0,运算结果是否为负数等。根据条件码ZF和SF来实现转跳。
语法如下:
je <label> #equal,若a==b则跳转,ZF==1 ? jne <label> #not equal,若a!=b则跳转,ZF==0 ? jg <label> #greater than,若a>b则跳转,ZF==0 && SF==OF ? jge <label> #greater than or equal to,若a>=b则跳转,SF==OF ? jl <label> #less than,若a<b则跳转,SF!=OF ? jle <label> #less than or equal to,若a<=b则跳转,SF!=OF||ZF==1
举例:
cmp eax, ebx #比较寄存器eax和ebx里的值 jg NEXT #若 eax> ebx,则跳转到 NEXT:
-
cmp/test指令。cmp指令用于比较两个操作数的值(同sub),test指令对两个操作数进行逐位与运算,这两类指令都不保存操作结果,仅根据运算结果设置CPU状态字中的条件码。
语法如下:
cmp <reg>,<reg> / test <reg>,<reg> cmp <reg>,<mem> / test <reg>,<mem> cmp <mem>,<reg> / test <mem>,<reg> cmp <reg>,<con> / test <reg>,<con>
注意,不能同时将内存,常数为地址码
cmp <mem>,<con> / test <mem>,<con>
举例:
cmp dword ptr [var],10 #将var指示的主存地址的4字节内容,与10比较 jne loop #如果相等则继续顺序执行;否则跳转到10p处执行 test eax,eax #测试eax是否为零 jz xxxx #为零则置标志ZF为1,转跳到xxxx处执行
-
call/ret指令。分别用于实现子程序(过程、函数等)的调用及返回。
语法如下:
call <label> ret
call指令首先将当前执行指令地址入栈,然后无条件转移到由标签指示的指令。与其他简单的跳转指令不同,call指令保存调用之前的地址信息(当call指令结束后,返回调用之前的地址)。
ret指令实现子程序的返回机制,ret指令弹出栈中保存的指令地址,然后无条件转移到保存的指令地址执行。cal和ret是程序(函数)调用中最关键的两条指令。
-
-
4.3.2 选择语句的机器级表示
常见的选择结构语句有if-then、if-then-else、case(或switch)等。编译器通过条件码(标志位)设置指令和各类转移指令来实现程序中的选择结构语句。
-
条件码(标志位)
除了整数寄存器,CPU还维护一组条件码(标志位)寄存器,它们描述了最近的算术或逻辑运算操作的属性。可以检测这些寄存器来执行条件分支指令,最常用的条件码如下:
- CF:进(借)位标志。最近无符号整数加(减)运算后的进(借)位情况。有进(借)位时,CF=1;否则CF=0。
- ZF:零标志。最近的操作的运算结果是否为0。若结果为0,ZF=1;否则ZF=0。
- SF:符号标志。最近的带符号数运算结果的符号。若为负,SF=1;否则SF=0。
- OF:溢出标志。最近的带符号数运算结果是否溢出。若溢出,OF=1;否则OF=0。
可见,OF和SF对无符号数运算来说没有意义,而CF对带符号数运算来说没有意义。
-
if语句
if-else 语句的通用形式如下:
if(a>b){ c=a; } else{ c=b; }
对应汇编代码如下:
mov eax,7 #假设变量a=7,存入eax mov ebx,6 #假设变量b=6,存入ebx cmp eax,ebx #比较变量a和b jg NEXT #若a>b,转移到NEXT: move ecx,ebx #假设用ecx存储变量c,令c=b ——> else 部分的逻辑 jmp END #无条件转移到END: NEXT: mov ecx,eax #假设用ecx存储变量c,令c=a ——> if 部分的逻辑 END:
此时if和else的顺序与原代码相反,可以通过对跳转条件取反(jg→jle),使其顺序与原代码相同:
mov eax,7 #假设变量a=7,存入eax mov ebx,6 #假设变量b=6,存入ebx cmp eax,ebx #比较变量a和b jle NEXT #若a≤b,转移到NEXT: move ecx,eax #假设用ecx存储变量c,令c=a ——> if 部分的逻辑 jmp END #无条件转移到END: NEXT: mov ecx,ebx #假设用ecx存储变量c,令c=b ——> else 部分的逻辑 END:
4.3.3 循环语句的机器级表示
常见的循环结构语句有while、for和do-while。汇编中没有相应的指令存在,可以用条件测试和转跳组合起来实现循环的效果,大多数编译器将这三种循环结构都转换为d0-while形式来产生机器代码。在循环结构中,通常使用条件转移指令来判断循环条件的结束。
-
for循环
int result = 0; for(int i=1;i<=100;i++){ result+=i; }//求1+2+3+...+100
-
while循环
int i = 1; int result = 0; while(i<=100){ result +=i; i++; }//求1+2+3+...+100
-
汇编指令翻译循环
mov eax,0 #用 eax保存 result,初值为0 mov edx,1 #用 edx保存 i,初始值为1 cmp edx,100 #比较 i和100 jg L2 #若i>100,转跳到 L2 执行 L1: #循环主体 add eax,edx #实现 result +=i inc edx #inc 自增指令,实现 i++ cmp edx,100 #比较i和100 jle L1 #若 i<=100,转跳到 L1 执行 L2: #跳出循环主体
用条件转移指令实现循环,需要4个部分构成:
- ①循环前的初始化——1、2句
- ②是否直接跳过循环?——3、4句
- ③循环主体——6、7句
- @是否继续循环?——8、9句
-
用loop指令实现循环
C语言形式:
for(int i=500;i>0;i--){ 做某些处理 }//循环500轮
汇编形式
mov ecx 500 #用ecx作为循环计数器 Looptop: #循环的开始 ... 做某些处理 ... loop Looptop #ecx--,若ecx!=0,跳转到Looptop
loop指令默认每轮对ecx进行减小操作,只能用ecx存轮次数。loop指令等价于:
dec ecx cmp ecx,0 jne Looptop
使用loop指令可能会使代码更清晰简洁,与跳转区分开来。
补充:loopx指令一-如loopnz,loopz
loopz——当ecx!=0&&ZF==0时,继续循环
loopnz——当ecx!=0&&ZF==1时,继续循环
4.3.4 过程调用的机器级表示
上面提到的call/ret指令主要用于过程调用,它们都属于一种无条件转移指令。
-
高级语言的函数调用
函数的栈帧(Stack Frame):保存函数大括号内定义的局部变量、保存函数调用相关的信息
假定过程P(调用者)调用过程Q(被调用者),过程调用的执行步骤如下:
- 1)P将入口参数(实参)放在Q能访问到的地方。
- 2)P将返回地址存到特定的地方,然后将控制转移到Q。
- 3)Q保存P的现场(通用寄存器的内容),并为自己的非静态局部变量分配空间。
- 4)执行过程Q。
- 5)Q恢复P的现场,将返回结果放到P能访问到的地方,并释放局部变量所占空间。
- 6)Q取出返回地址,将控制转移到P。
步骤2是由call指令实现的,步骤6由ret指令返回到过程P。
-
如何访问栈帧
栈的位置:
-
栈寄存器
- ebp:指向当前栈的“底部"
- esp:指向当前栈的“顶部"
-
利用push、pop的入栈出栈操作(push、pop默认以4字节为单位)
- Push操作:先让esp减4,再将数据压入
- Pop操作:栈顶元素写入寄存器或主存地址,再让esp加4
-
利用mov的入栈出栈操作
mov指令,结合esp、ebp 指针访问栈数据
注:可以用减法/加法指;即sub/add修改找顶指针esp的值。
-
-
切换栈帧
-
call指令
- ①将IP旧值压栈保存 (保存在函数的栈帧顶部)
- ②设置IP新值、无条件转移至被调用函数的第一条指令
-
return指令
从函数的栈顶部找到IP旧值,将其出栈并恢复IP寄存器
-
enter指令(更新ebp)
等价于push ebp + move ebp,esp;保存上一层函数的栈帧基地址;0地址指令
-
leave指令(更新esp)
等价于mov esp,ebp + pop ebp;让esp指向当前栈帧底部
-
-
栈内内容
- gcc编译器将每个栈帧大小设置为16B的整数倍(当前函数的除外),因此栈帧内可能出现空闲未使用的区域。
- 通常将局部变量集中存储在栈帧底部区域
- 通常将调用参数集中存储在栈帧顶部区域
- 栈帧最底部一定是上一层栈基址(ebp旧值)
- 栈帧最顶部一定是返回地址(当前函数的栈帧除外)
-
函数调用时栈的变化
4.4 CISC和RISC的基本概念
4.4.1 复杂指令系统计算机(CISC)
-
设计思路:一条指令完成一个复杂的基本功能。
-
代表:x86架构,主要用于笔记本、台式机等
-
特点:
- 1)指令系统复杂庞大,指令数目一般为200条以上。
- 2)指令的长度不固定,指令格式多,寻址方式多。
- 3)可以访存的指令不受限制。
- 4)各种指令使用频度相差很大。
- 5)各种指令执行时间相差很大,大多数指令需多个时钟周期才能完成。
- 6)控制器大多数采用微程序控制。有些指令非常复杂,以至于无法采用硬连线控制。
- 7)难以用优化编译生成高效的目标代码程序。
-
问题
80-20规律:典型程序中80%的语句仅仅使用处理机中20%的指令
4.4.2 精简指令系统计算机(RISC)
- 设计思路:一条指令完成一个基本“动作”,多条指令组合完成一个复杂的基本功能。
- 代表:ARM架构、MIPS架构,主要用于手机、平板等
- 特点:
- 1)选取使用频率最高的一些简单指令,复杂指令的功能由简单指令的组合来实现。
- 2)指令长度固定,指令格式种类少,寻址方式种类少。
- 3)只有Load/Store(取数/存数)指令访存,其余指令的操作都在寄存器之间进行。
- 4)CPU中通用寄存器的数量相当多。
- 5)RISC一定采用指令流水线技术,大部分指令在一个时钟周期内完成。
- 6)以硬布线控制为主,不用或少用微程序控制。
- 7)特别重视编译优化工作,以减少程序执行时间。
4.4.3 CISC和RISC的比较
类别 | CISC | RISC |
---|---|---|
指令系统 | 复杂,庞大 | 简单,精简 |
指令数目 | 一般大于200条 | 般小于100条 |
指令字长 | 不固定 | 定长 |
可访存指令 | 不加限制 | 只有Load/store指令 |
各种指令执行时间 | 相差较大 | 绝大多数在一个周期内完成 |
各种指令使用频度 | 相差很大 | 都比较常用 |
通用寄存器数量 | 较少 | 多 |
目标代码 | 难以用优化编译生成高效的目标代码程序 | 采用优化的编译程序,生成代码较为高效 |
控制方式 | 绝大多数为微程序控制 | 绝大多数为组合逻辑控制 |
指令流水线 | 可以通过一定方式实现 | 必须实现 |
5 中央处理器
5.1 CPU的功能和基本结构
5.1.1 CPU的功能
-
组成
中央处理器(CPU)由运算器和控制器组成。
-
控制器的功能是负责协调并控制计算机各部件执行程序的指令序列,包括取指令、分析指令和执行指令;
-
运算器的功能是对数据进行加工
-
-
功能
- 1)指令控制。完成取指令、分析指令和执行指令的操作,即程序的顺序控制。
- 2)操作控制。一条指令的功能往往由若干操作信号的组合来实现。CPU管理并产生由内存取出的每条指令的操作信号,把各种操作信号送往相应的部件,从而控制这些部件按指令的要求进行动作。
- 3)时间控制。对各种操作加以时间上的控制。时控制要为每条指令按时间顺序提供应有的控制信号。
- 4)数据加工。对数据进行算术和逻辑运算。
- 5)中断处理。对计算机运行过程中出现的异常情况和特殊请求进行处理。
5.1.2 CPU的基本结构
-
运算器
- 功能:接收从控制器送来的命令并执行相应的动作,对数据进行加工处理。
- 组成:
- 算术逻辑单元(ALU)。主要功能是进行算术/逻辑运算。
- 暂存寄存器。用于暂存从主存读来的数据,该数据不能存放在通用寄存器中,否则会破坏其原有内容。暂存寄存器对应用程序员是透明的。
- 累加寄存器(ACC)。它是一个通用寄存器,用于暂时存放ALU运算的结果信息,可以作为加法运算的一个输入端。
- 通用寄存器组。如AX、BX、CX、DX、SP等,用于存放操作数(包括源操作数、目的操作数及中间结果)和各种地址信息等。SP是堆栈指针,用于指示栈顶的地址。
- 程序状态字寄存器(PSW)。保留由算术逻辑运算指令或测试指令的结果而建立的各种状态信息,如溢出标志(OF)、符号标志(SF)、零标志(ZF)、进位标志(CF)等。PSW中的这些位参与并决定微操作的形成。
- 移位器。对操作数或运算结果进行移位运算。
- 计数器(CT)。控制乘除运算的操作步数。
-
控制器
- 功能:协调并控制计算机各部件执行程序的指令序列,基本功能如下:
- 分析指令:操作码译码(分析本条指令要完成什么操作);产生操作数的有效地址。
- 执行指令:根据分析指令得到的“操作命令”和“操作数地址”,形成操作信号控制序列,控制运算器、存储器以及I/O设备完成相应操作
- 中断处理:管理总线及输入输出;处理异常情况(如掉电)和特殊请求(如打印机请求打印字符)。
- 组成:
- 程序计数器(PC)。用于指出欲执行指令在主存中的存放地址。CPU根据PC的内容去主存中取指令。因程序中指令(通常)是顺序执行的,所以PC有自增功能。容量:log2存储容量
- 指令寄存器(IR)。用于保存当前正在执行的那条指令。容量:指令字长
- 指令译码器。仅对操作码字段进行译码,向控制器提供特定的操作信号。
- 存储器地址寄存器(MAR)。用于存放要访问的主存单元的地址。容量:log2存储容量
- 存储器数据寄存器(MDR)。用于存放向主存写入的信息或从主存读出的信息。容量:存储字长
- 时序系统。用于产生各种时序信号,它们都由统一时钟(CLOCK)分频得到。
- 微操作信号发生器。根据IR的内容(指令)、PSW的内容(状态信息)及时序信号,产生控制整个计算机系统所需的各种控制信号,其结构有组合逻辑型和存储逻辑型两种。
- 功能:协调并控制计算机各部件执行程序的指令序列,基本功能如下:
-
基本架构图
-
用户可见寄存器:通用寄存器组、程序状态字寄存器、程序计数器;可对这类寄存器编程
-
用户不可见的寄存器:存储器地址寄存器、存储器数据寄存器、指令寄存器、暂存寄存器;不可对这类寄存器编程
-
5.2 指令执行过程
5.2.1 指令周期
-
概念
-
指令周期:CPU从主存中取出并执行一条指令的时间称为指令周期,不同指令的指令周期可能不同。
-
机器周期:也称节拍或T周期,指令周期常用若干机器周期来表示,它是CPU操作的最基本单位。
-
时钟周期:一个机器周期包含若干时钟周期。
图(a)为定长的机器周期,每个机器周期包含4个节拍(T);图(b)所示为不定长的机器周期,每个机器周期包含的节拍数可以为4个,也可以为3个。
每个指令周期内机器周期数可以不等,每个机器周期内的节拍数也可以不等。
-
-
指令周期流程
一个完整的的指令周期应包括取指、间址、执行和中断4个周期。
上述4个工作周期都有CPU访存操作,只是访存的目的不同。取指周期是为了取指令,间址周期是为了取有效地址,执行周期是为了取操作数,中断周期是为了保存程序断点。
为了区别不同的工作周期,在CPU内设置4个标志触发器FE、IND、EX和INT,它们分别对应取指、间址、执行和中断周期,并以“1”状态表示有效,分别由1→FE、1→IND、1→EX和1→NT这4个信号控制。
5.2.2 指令周期的数据流
-
取指周期
任务:取指周期的任务是根据PC中的内容从主存中取出指令代码并存放在IR中
数据流:
-
PC-①->MAR-②->地址总线-③->主存
- 当前指令地址送至存储器地址寄存器,记做:(PC)→ MAR
-
CU发出读命令-④->控制总线-⑤->主存
- CU发出读信号,经控制总线传到主存,记做:1→R
-
主存-⑥->数据总线-⑦->MDR-⑧->IR (存放指令)
-
将MAR所指主存内容经数据总线送入MDR,记做:M(MAR)→MDR
-
将MDR中的内容(此时是指令)送入IR,记做:(MDR)→IR
-
-
CU发出控制信号-⑨->PC内容加1
- CU发出控制信号,形成下一条指令地址,记做:(PC)+1→PC
-
-
间址周期
任务:间址周期的任务是取操作数有效地址。
数据流:
-
Ad(IR) (或MDR)-①->MAR-②->地址总线-③->主存
- 将指令的地址码送入MAR,记做:Ad(IR)→ MAR或Ad(MDR)→ MAR
-
CU发出读命令-④->控制总线-⑤->主存
- CU发出控制信号,启动主存做读操作,记做:1→R
-
主存-⑥->数据总线-⑦->MDR (存放有效地址)
-
将MAR所指主存中的内容经数据总线送入MDR,记做:M(MAR)→ MDR
-
将有效地址送至指令的地址码字段,记做:(MDR)→ Ad(IR)
-
其中,Ad(IR)表示取出IR中存放的指令字的地址字段
-
-
执行周期
执行周期的任务是根据IR中的指令字的操作码和操作数通过ALU操作产生执行结果。
不同指令的执行周期操作不同,因此没有统一的数据流向。
-
中断周期
任务:处理中断请求。暂停当前任务去完成其他任务,为了能够恢复当前任务,需要保存断点。
一般使用堆栈来保存断点,这里用SP表示栈顶地址,假设SP指向栈顶元素,进栈操作是先修改指针,后存入数据。
数据流:
-
CU控制将SP减1,SP-①->MAR-②->地址总线-③->主存
-
CU控制将SP减1,修改后的地址送入MAR记做:(SP)-1 → SP,(SP)→ MAR
本质上是将断点存入某个存储单元,假设其地址为a,故可记做:a→MAR
-
-
CU发出写命令-④->控制总线-⑤->主存
- CU发出控制信号,启动主存做写操作,记做:1→ W
-
PC-⑥->MDR-⑦->数据总线-⑧->主存 (程序断点存入主存)
- 将断点(PC内容)送入MDR,记做:(PC)→ MDR
-
CU (中断服务程序的入口地址) -⑨->PC
- CU控制将中断服务程序的入口地址(由向量地址形成部件产生)送入PC,记做:向量地址→PC
-
5.2.3 指令执行方案
一个指令周期通常要包括几个时间段(执行步骤),每个步骤完成指令的一部分功能,几个依次执行的步骤完成这条指令的全部功能。
-
单指令周期
-
特点:对所有指令都选用相同的执行时间来完成,指令之间串行执行。
指令之间串行执行,即下一条指令只能在前一条指令执行结束后才能启动。
-
时钟周期:时钟周期取决于执行时间最长的指令的执行时间。
对于那些本来可以在更短时间内完成的指令,要使用较长的周期来完成,会降低整个系统的运行速度。
-
-
多指令周期
- 特点:对不用类型的指令选用不同的执行步骤来完成,指令之间串行执行。
- 时钟周期:可选用不同个数的时钟周期来完成不同指令的执行过程,需要更复杂的硬件设计。
-
流水线方案
- 特点:指令之间并行执行。
- 时钟周期:在每一个时钟周期启动一条指令,尽量让多条指令同时运行,但各自处在不同的执行步骤中。
5.3 数据通路的功能和基本结构
5.3.1 数据通路的功能
-
数据通路:数据在功能部件之间传送的路径。
数据通路描述了信息从什么地方开始,中间经过哪个寄存器或多路开关,最后传送到哪个寄存器,这些都需要加以控制。
-
构成:包括数据通路上流经的部件,如ALU、通用寄存器、状态寄存器、异常和中断处理逻辑等。
数据通路由控制部件控制,控制部件根据每条指令功能的不同生成对数据通路的控制信号。
-
功能:实现CPU内部的运算器与寄存器及寄存器之间的数据交换。
5.3.2 数据通路的基本结构
-
基本结构类型
- CPU 内部单总线方式:将所有寄存器的输入和输出端连接到一条公共通路上
- 结构比较简单,但数据传输存在较多的冲突现象,性能较低
- CPU内部三总线方式:将所有寄存器入的输入和输出端连接到多条公共通路上
- 同时在多个总线上传送不同的数据,效率提高
- 专用数据通路方式:根据指令执行过程中的数据和地址的流动方向安排连接线路
- 避免使用共享的总线,性能较高,但硬件量大
- CPU 内部单总线方式:将所有寄存器的输入和输出端连接到一条公共通路上
-
CPU内部单总线数据通路
-
寄存器之间的数据传送
寄存器之间的数据传送可通过CPU 内部总线完成。
上图中,以PC寄存器为例,把PC内容送至MAR,实现传送操作的流程及控制信号为
(PC)→Bus PCout有效,PC内容→总线 Bus→MAR MARin有效,总线→MAR
-
主存与CPU之间的数据传送
主存与CPU之间的数据传送也要借助CPU内部总线完成。
以CPU从主存读取指令为例,实现传送操作的流程及控制信号为
(PC)→Bus→MAR PCout和MARin有效,现行指令地址→MAR 1→R CU发读命令(过控制总线发出,图中未画出) MEM(MAR)→MDR MDRin有效 MDR→Bus→IR MDRout和IRin有效,现行指令→IR
-
执行算术或逻辑运算
执行算术或逻辑操作时,由于ALU本身是没有内部存储功能的组合电路,因此如要执行加法运算,相加的两个数必须在ALU的两个输入端同时有效。
以一条加法指令为例,微操作序列及控制信号为:
Ad(IR)→Bus→MAR MDRout和MARin有效 1→R CU发读命令 MEM(MAR)→MDR MDRin有效 MDR→Bus→Y MDRout和Yin有效,操作数→Y (ACC)+(Y)→Z ACCout和ALUin有效,CU向ALU发送加命令 Z→ACC Zout和ACCin有效,结果→ACC
-
5.4 控制器的功能和工作原理
5.4.1 控制器的结构和功能
-
控制器的结构
下图介绍了计算机硬件系统的五大功能部件及其连接关系。它们通过数据总线、地址总线和控制总线连接在一起,其中点画线框内的是控制器部件。
- 运算器部件通过数据总线与内存储器、输入设备和输出设备传送数据。
- 输入设备和输出设备通过接口电路与总线相连接。
- 内存储器、输入设备和输出设备从地址总线接收地址信息,从控制总线得到控制信号,通过数据总线与其他部件传送数据。
- 控制器部件从数据总线接收指令信息,从运算器部件接收指令转移地址,送出指令地址到地址总线,还要向系统中的部件提供它们运行所需要的控制信号。
-
控制的功能
- 从主存中取出一条指令,并指出下一条指令在主存中的位置。
- 对指令进行译码或测试,产生相应的操作控制信号,以便启动规定的动作。
- 指挥并控制 CPU、主存、输入和输出设备之间的数据流动方向。
5.4.2 硬布线控制器
硬布线控制器的基本原理是根据指令的要求、当前的时序及外部和内部的状态,按时间的顺序发送一系列微操作控制信号。它由复杂的组合逻辑门电路和一些触发器构成,因此又称组合逻辑控制器。
-
硬布线控制单元图
指令的操作码是决定控制单元发出不同操作命令(控制信号)的关键。为了简化控制单元(CU)的逻辑,将指令的操作码译码和节拍发生器从CU分离出来,便可得到简化的控制单元图,如下图所示。
-
输入:
- 经指令译码器译码产生的指令信息。
- 时序系统产生的机器周期信号和节拍信号。
- 来自执行单元的反馈信息即标志。
-
输出:
-
CPU内部的控制信号:寄存器之间的数据传输、PC的修改、控制ALU进行相应的运算
-
到控制总线的控制信号:
到存储器:访存控制信号MREQ、读命令RD、写命令WR
到I/O设备:访问I/O设备的控制信号IO
中断响应信号INTA、总线响应信号HLDA
-
-
-
硬布线控制器的微操作
微操作命令分析。控制单元具有发出各种操作命令(控制信号)序列的功能。这些命令与指令有关,而且必须按一定次序发出,才能使机器有序地工作。
执行程序的过程中,对于不同的指令,控制单元需发出各种不同的微操作命令。一条指令分为3个工作周期:取指周期、间址周期和执行周期。下面分析各个子周期的微操作命令。
-
取指周期的微操作命令。无论是什么指令,取指周期都需有下列微操作命令:
(PC)→MAR 现行指令地址→MAR 1→R 命令存储器读 M(MAR)→MDR 现行指令从存储器中读至MDR (MDR)→IR 现行指令→IR OP(IR)→IR 指令的操作码→CU译码 (PC)+1→PC 形成下一条指令的地址
-
间址周期的微操作命令。间址周期完成取操作数地址的任务,具体微操作命令如下:
Ad(IR)→MAR 将指令字中的地址码(形式地址)→MAR 1→R 命令存储器读 M(MAR)→MDR 将有效地址从存储器读至MDR
-
执行周期的微操作命令。执行周期的微操作命令视不同指令而定。
a.非访存指令。
CLA 清ACC COM 取反 SHR 算术右移 CSL 循环左移 STP 停机指令
b.访存指令
ADD X 加法指令 Ad(IR)→MAR,1→R M(MAR)→MDR (ACC)+(MDR)→ACC STA X 存数指令 Ad(IR)→MAR,1→W (ACC)→MDR LDA X 取数指令
c.转移指令
JMP X 无条件转移指令 BAN X 条件转移指令(负则转)
-
-
CPU的控制方式:产生不同微操作命令序列所用的时序控制方式。
-
同步控制方式。所谓同步控制方式,是指系统有一个统一的时钟,所有的控制信号均来自这个统一的时钟信号。通常以最长的微操作序列和最烦琐的微操作作为标准,采取完全统一的、具有相同时间间隔和相同数目的节拍作为机器周期来运行不同的指令。
同步控制方式的优点是控制电路简单,缺点是运行速度慢。
-
异步控制方式。异步控制方式不存在基准时标信号,各部件按自身固有的速度工作,通过应答方式进行联络。
异步控制方式的优点是运行速度快,缺点是控制电路比较复杂。
-
联合控制方式。联合控制方式是介于同步、异步之间的一种折中。这种方式对各种不同的指令的微操作实行大部分采用同步控制、小部分采用异步控制的办法。
-
-
硬布线控制器设计步骤
- 分析每个阶段的微操作序例
- 选择CPU的控制方式
- 安排微操作时序
- 电路设计
5.4.3 微程序控制器
微程序控制器采用存储逻辑实现,也就是把微操作信号代码化,使每条机器指令转化成为一段微程序并存入一个专门的存储器(控制存储器)中,微操作控制信号由微指令产生。
-
微程序控制的基本概念
微程序设计思想就是将每条机器指令编写成一个微程序,每个微程序包含若干微指令,每条微指令对应一个或几个微操作命令。
这些微程序可以存到一个控制存储器中,用寻址用户程序机器指令的办法来寻址每个微程序中的微指令。
- 微命令与微操作
- 一条机器指令可以分解成一个微操作序列,这些微操作是计算机中最基本的、不可再分解的操作。
- 在微程序控制的计算机中,将控制部件向执行部件发出的各种控制命令称为微命令,它是构成控制序列的最小单位。
- 微命令和微操作是一一对应的。微命令是微操作的控制信号,微操作是微命令的执行过程。
- 微命令有相容性和互斥性之分。
- 相容性微命令是指那些可以同时产生、共同完成某一些微操作的微命令;
- 而互斥性微命令是指在机器中不允许同时出现的微命令。
- 微指令与微周期
- 微指令是若千微命令的集合。存放微指令的控制存储器的单元地址称为微地址。
- 操作控制字段,又称微操作码字段,用于产生某一步操作所需的各种操作控制信号
- 顺序控制字段,又称微地址码字段,用于控制产生下一条要执行的微指令地址。
- 微周期是指执行一条微指令所需的时间,通常为一个时钟周期。
- 微指令是若千微命令的集合。存放微指令的控制存储器的单元地址称为微地址。
- 主存储器与控制存储器
- 主存储器用于存放程序和数据,在CPU外部,用RAM实现
- 控制存储器 (CM) 用于存放微程序,在CPU内部,用ROM实现
- 程序与微程序
- 程序是指令的有序集合,用于完成特定的功能
- 微程序是微指令的有序集合,一条指令的功能由一段微程序来实现
- 寄存器区分
- 地址寄存器 (MAR)。用于存放主存的读/写地址。
- 微地址寄存器 (CMAR)。用于存放控制存储器的读/写微指令的地址,
- 指令寄存器 (IR)。用于存放从主存中读出的指令。
- 微指令寄存器(CMDR或μIR)。用于存放从控制存储器中读出的微指令。
- 微命令与微操作
-
微程序控制器组成和工作过程
-
微程序控制器的基本组成
- 控制存储器。它是微程序控制器的核心部件,用于存放各指令对应的微程序,控制存储器可用只读存储器ROM构成
- 微指令寄存器。用于存放从CM中取出的微指令,它的位数同微指令字长相等
- 微地址形成部件。用于产生初始微地址和后维微地址,以保证微指令的连续执行
- 微地址寄存器。接收微地址形成部件送来的微地址,为在CM中读取微指令作准备
-
微程序控制器的工作过程
- ①执行取微指令公共操作。具体的执行是:在机器开始运行时,自动将取指微程序的入口地址送入CMAR,并从CM中读出相应的微指令送入CMDR。取指微程序的入口地址一般为CM的0号单元,当取指微程序执行完后,从主存中取出的机器指令就已存入指令寄存器中
- ②由机器指令的操作码字段通过微地址形成部件产生该机器指令所对应的微程序的入口地址,并送入CMAR
- ③从CM中逐条取出对应的微指令并执行。
- ④执行完对应于一条机器指令的一个微程序后,又回到取指微程序的入口地址,继续第①步,以完成取下一条机器指令的公共操作。
-
微程序和机器指令
一条机器指令对应一个微程序。由于任何机器指令的取指令操作都是相同的,因此可将取指令操作的微命令统一编成一个微程序,这个微程序只负责将指令从主存单元中取出并送至指令寄存器。
-
-
微指令的编码方式
微指令的编码方式又称微指令的控制方式,是指如何对微指令的控制字段进行编码,以形成控制信号。编码的目标是在保证速度的情况下,尽量缩短微指令字长。
-
直接编码(直接控制)方式
- 编码方式:微指令的微命令字段中每位都代表一个微命令。选用或不选用某个微命令,只要将表示该微命令的对应位设置成1或0即可。每个微命令对应并控制数据通路中的一个微操作。
微指令的直接编码方式如下图所示。
- 优点:简单、直观,执行速度快,操作并行性好
- 缺点:微指令字长过长,n个微命令就要求微指令的操作字段有n位,造成控制存储器容量极大
-
字段直接编码方式
- 编码方式:将微指令的微命令字段分成若干小字段,把互斥性微命令组合在同一字段中,把相容性微命令组合在不同字段中,每个字段独立编码,每种编码代表一个微命令且各字段编码含义单独定义与其他字段无关。
-
优点:可以缩短微指令字长
-
缺点:因为要通过译码电路后再发出微命令,因此比直接编码方式慢
-
分段原则:
①互斥性微命令分在同一段内,相容性微命今分在不同段内。
②每个小段中包含的信息位不能太多,否则将增加译码线路的复杂性和译码时间
③一般每个小段还要留出一个状态,表示本字段不发出任何微命令。因此,当某字段的长度为3位时,最多只能表示7个互斥的微命令,通常用000表示不操作
-
字段间接编码方式
-
编码方式:一个字段的某些微命令需由另一个字段中的某些微命令来解释,由于不是靠字段直接译码发出的微命令,因此称为字段间接编码,又称隐式编码。
-
优点:可进一步缩短微指令字长
-
缺点:但因削弱了微指令的并行控制能力,因此通常作为字段直接编码方式的一种辅助手段。
-
-
-
微指令的地址形成方式
后继微地址的形成主要有以下两大基本类型:
-
直接由微指令的下地址字段指出。微指令格式中设置一个下地址字段,由微指令的下地址字段直接指出后维微指令的地址,这种方式又称断定方式。
-
根据机器指令的操作码形成。机器指令取至指令寄存器后,微指令的地址由操作码经微地址形成部件形成
-
其他方式:
①增量计数器法,即(CMAR)+1→CMAR,适用于后继微指令的地址连续的情况
②根据各种标志决定微指令分支转移的地址。
③通过测试网络形成。
④由硬件直接产生微程序入口地址,
-
-
微指令的格式
微指令格式与微指令的编码方式有关,通常分水平型微指令和垂直型微指令两种。
-
水平型微指令。
从编码方式看,直接编码、字段直接编码、字段间接编码和混合编码都属于水平型微指令。一条水平型微指令定义并执行几种并行的基本操作,指令字中的一位对应一个控制信号,有输出时为1,否则为0。
- 优点是微程序短,执行速度快
- 缺点是微指令长,编写微程序较麻烦
-
垂直型微指令。
垂直型微指令的特点是采用类似机器指令操作码的方式,在微指令中设置微操作码字段,采用微操作码编译法,由微操作码规定微指令的功能。一条垂直型微指令只能定义并执行一种基本操作。
- 微指令短、简单、规整,便于编写微程序
- 微程序长执行速度慢,工作效率低
-
混合型微指令:在垂直型的基础上增加一些不太复杂的并行操作。
微指令较短,仍便于混合型微指令编写;微程序也不长,执行速度加快。
-
水平型微指令和垂直型微指令的比较
比较 水平微指令 垂直微指令 并行能力 强 弱 执行时间 长 长 微指令字长短 指令字较长;微程序短 微指令字较短;微程序长 编程难易程度 难 简单
-
-
微程序控制单元的设计步骤
- 写出对应机器指令的微操作命令及节拍安排。
- 确定微指令格式。
- 编写微指令码点。
-
硬布线和微程序控制器的特点
对比 微程序控制器 硬布线控制器 工作原理 微操作控制信号以微程序的形式存放在控制存储器中,执行指令时读出即可 微操作控制信号由组合逻辑电路根据当前的指令码、状态和时序,即时产生 执行速度 慢 快 规整性 较规整 烦琐、不规整 应用场合 CISC CPU RISC CPU 易扩充性 易扩充修改 困难
5.5 异常和中断机制
5.5.1 异常和中断的基本概念
-
异常:由CPU内部产生的意外事件被称为异常,有些教材中也称内中断。
是CPU执行一条指令时,由CPU在其内部检测到的、与正在执行的指令相关的同步事件;
-
中断:由来自CPU外部的设备向CPU发出的中断请求被称为中断,通常用于信息的输入和输出,有些教材中也称外中断。
是一种典型的由外部设备触发的、与当前正在执行的指令无关的异步事件。
5.5.2 异常和中断的分类
-
异常的分类
-
故障(Fault)
-
定义:指在引起故障的指令启动后、执行结束前被检测到的异常事件。
-
例:指令译码时,出现“非法操作码”;取数据时,发生**“缺段”或“缺页"**;执行整数除法指令时,发现“除数为0”等。
-
处理:内核程序修复后会把CPU使用权还给应用程序,让它继续执行。(如缺页中断)
对于“非法操作码”和“除数为0”等,因为无法通过异常处理恢复故障,必需终止程序。
-
-
自陷(Trap)
- 定义:也称陷阱或陷入,它是预先安排的一种“异常”事件,就像预先设定的“陷阱”一样。
- 例:“断点调试”、单步跟踪、系统调用
- 处理:CPU在执行完自陷指令后,自动根据不同“陷阱”类型进行相应的处理,然后返回到自陷指令的下一条指令执行。注意,当自陷指令是转移指令时,并不是返回到下一条指令执行,而是返回到转移目标指令执行。
故障和自陷异常属于软件中断(程序性异常);终止和外中断属于硬件中断
-
终止(Abort)
- 定义:由致命错误起,内核程序无法修复该错误,一股直接终止该应用程序。
- 例:如控制器出错、存储器校验错误、总线错误等;此时,只能调出中断服务程序来重启系统。
-
-
中断的分类
中断是指来自CPU外部、与CPU执行指令无关的事件引起的中断,包括IO设备发出的IO中断(如键盘输入、打印机缺纸等),或发生某种特殊事件(如用户按Esc键、定时器计数时间到)等。
外部I/O设备通过特定的中断请求信号线向CPU提出中断请求,CPU每执行完一条指令就检查中断请求信号线,如果检测到中断请求,则进入中断响应周期。
-
可屏蔽中断
指通过可屏蔽中断请求线INTR向CPU发出的中断请求。CPU可以通过在中断控制器中设置相应的屏蔽字来屏蔽它或不屏蔽它,被屏蔽的中断请求将不被送到CPU。
-
不可屏蔽中断
指通过专门的不可屏蔽中断请求线NMI向CPU发出的中断请求,通常是非常紧急的硬件故障,如电源掉电等。这类中断请求信号不可被屏蔽,以让CPU快速处理这类紧急事件。
-
-
中断和异常的不同点
- “缺页”或“溢出”等异常事件是由特定指令在执行过程中产生的,而中断不和任何指令相关联,也不阻止任何指令的完成。
- 异常的检测由CPU自身完成,不必通过外部的某个信号通知CPU。对于中断,CPU必须通过中断请求线获取中断源的信息,才能知道哪个设备发生了何种中断。
5.5.3 异常和中断响应过程
CPU对异常和中断响应的过程可分为:关中断、保存断点和程序状态、识别异常和中断并转到相应的处理程序。
-
关中断
在保存断点和程序状态期间,不能被新的中断打断,因此要禁止响应新的中断,即关中断。
通常通过设置**“中断允许”(IF)触发器**来实现,
- 若IF置为1,则为开中断,表示允许响应中断;
- 若IF置为0,则表示关中断,表示不允许响应中断。
-
保存断点和程序状态
为了能在异常和中断处理后正确返回到被中断的程序继续执行,必须将程序的断点(返回地址)送到栈或特定寄存器中。通常保存在栈中,这是为了支持异常或中断的嵌套。
异常和中断处理后可能还要回到被中断的程序继续执行,被中断时的程序状态字寄存器PSWR的内容也需要保存在栈或特定寄存器中,在异常和中断返回时恢复到PSWR中。
-
识别异常和中断并转到相应的处理程序
异常和中断源的识别有软件识别和硬件识别两种方式。
- 软件识别方式是指CPU设置一个异常状态寄存器,用于记录异常原因。操作系统使用一个统一的异常或中断查询程序,按优先级顺序查询异常状态寄存器,以检测异常和中断类型,先查询到的先被处理,然后转到内核中相应的处理程序。
- 硬件识别方式又称向量中断,异常或中断处理程序的首地址称为中断向量,所有中断向量都存放在中断向量表中。每个异常或中断都被指定一个中断类型号。在中断向量表中,类型号和中断向量一一对应,因而可以根据类型号快速找到对应的处理程序。
5.6 指令流水线
5.6.1 指令流水线的基本概念
可从两方面提高处理机的并行性:
①时间上的并行技术,将一个任务分解为几个不同的子阶段,每个阶段在不同的功能部件上并行执行,以便在同一时刻能够同时执行多个任务,进而提升系统性能,这种方法被称为流水线技术。
②空间上的并行技术,在一个处理机内设置多个执行相同任务的功能部件,并让这些功能部件并行工作,这样的处理机被称为超标量处理机。
-
指令流水的定义
一条指令的执行过程可以分为以下5个阶段:
- 取指(IF):从指令存储器或Cache 中取指令。
- 译码/读寄存器(ID):操作控制器对指令进行译码,同时从寄存器堆中取操作数。
- 执行/计算地址(EX):执行运算操作或计算地址。
- 访存(MEM):对存储器进行读写操作。
- 写回(WB):将指令执行结果写回寄存器堆。
把k+1条指令的取指阶段提前到第k条指令的译码阶段,从而将第k+1条指令的译码阶段与第k条指令的执行阶段同时进行,如图所示。
理想情况下,每个时钟周期都有一条指令进入流水线,每个时钟周期都有一条指令完成,每条指令的时钟周期数(即CPI)都为1。
为了利于实现指令流水线,指令集应具有如下特征:
- 1)指令长度应尽量一致,有利于简化取指令和指令译码操作。否则,取指令所花时间长短不一,使取指部件极其复杂,且也不利于指令译码。
- 2)指令格式应尽量规整,尽量保证源寄存器的位置相同,有利于在指令未知时就可取寄存器操作数,否则须译码后才能确定指令中各寄存器编号的位置。
- 3)采用Load/Store指令,其他指令都不能访问存储器,这样可把Load/Store指令的地址计算和运算指令的执行步骤规整在同一个周期中,有利于减少操作步骤。
- 4)数据和指令在存储器中“对齐”存放。这样,有利于减少访存次数,使所需数据在一个流水段内就能从存储器中得到。
-
流水线的表示方法
通常用时空图来直观地描述流水线的执行情况。
在时空图中,横坐标表示时间,它被分割成长度相等的时间段T;纵坐标为空间,表示当前指令所处的功能部件。
只有大量连续任务不断输入流水线,才能充分发挥流水线的性能,而指令的执行正好是连续不断的,非常适合采用流水线技术。对于其他部件级流水线,如浮点运算流水线,同样也仅适合于提升浮点运算密集型应用的性能,对于单个运算是无法提升性能的。
5.6.2 流水线的基本实现
在单周期实现中,这5个功能段是串连在一起的,如下图所示。
虽然不是所有指令都必须经历完整的5个阶段,但只能以执行速度最慢的指令作为设计其时钟周期的依据,单周期CPU的时钟频率取决于数据通路中的关键路径(最长路径),因此单周期CPU指令执行效率不佳。
-
流水线的数据通路
一个5段流水线数据通路如下图所示。
- IF段包括程序计数器(PC)、指令存储器、下条指令地址的计算逻辑;
- ID段包括操作控制器、取操作数逻辑、立即数符号扩展模块;
- EX段主要包括算术逻辑单元(ALU)、分支地址计算模块;
- MEM段主要包括数据存储器读写模块;
- WB段主要包括寄存器写入控制模块。
每个流水段后面都需要增加一个流水寄存器,用于锁存本段处理完成的数据和控制信号,以保证本段的执行结果能在下个时钟周期给下一流水段使用。
-
流水线的控制信号
每个流水寄存器中保存的信息包括:
- ①后面流水段需要用到的所有数据信息,包括PC+4、指令、立即数、目的寄存器、ALU运算结果、标志信息等,它们是前面阶段在数据通路中执行的结果,
- ②前面传递过来的后面各流水段要用到的所有控制信号。
-
流水线的执行过程
由于流水线的特殊结构,所有指令都需要完整经过流水线的各功能段,只不过某些指令在某些功能段内没有任何实质性的操作,只是等待一个时钟周期,这也就意味着单条指令的执行时间还是5个功能段时间延迟的总和。
-
取指(IF)
从存储器中根据程序计数器PC的值取出一条指令,并将其放入指令寄存器IR中,同时更新PC的值为下一条指令的地址。
-
译码/读寄存器(ID)
对IR中的指令进行译码,确定指令的类型、操作码和操作数,以及要使用的寄存器或立即数。如果是转移指令,还要计算转移目标地址和判断转移条件。
-
执行/计算地址(EX)
根据指令的类型和操作码,对ID阶段读出的操作数进行相应的运算或操作,如加减乘除、逻辑运算、移位等。运算结果暂存在ALU输出寄存器中。
-
访存(MEM)
如果指令需要访问存储器,如加载或存储指令,那么在这个阶段用EX阶段计算出的有效地址从存储器中读出或写入数据。如果是分支指令,还要判断是否需要更新PC的值为转移目标地址。
-
写回(WB)
将EX或MEM阶段得到的结果写回到目标寄存器中,完成一条指令的执行。
-
5.6.3 流水线的冒险与处理
在指令流水线中,可能会遇到一些情况使得流水线无法正确执行后续指令而引起流水线阻塞或停顿,这种现象称为流水线冒险。
-
结构冒险(资源冲突)
由于多条指令在同一时刻争用同一资源而形成的冲突,又称结构相关。
解决办法:
- 前一指令访存时,使后一条相关指令(以及其后续指令)暂停一个时钟周期。
- 资源重复配置:单独设置数据存储器和指令存储器,使取数和取指令操作各自在不同的存储器中进行。
-
数据冒险(数据冲突)
在一个程序中,下一条指令会用到当前指令计算出的结果,此时这两条指令发生数据冲突。
- 写后读(ReadAfterWrite,RAW)相关:表示当前指令将数据写入寄存器后,下一条指令才能从该寄存器读取数据。否则,先读后写,读到的就是错误(旧)数据。
- 读后写(WriteAfterRead,WAR)相关:表示当前指令读出数据后,下一条指令才能写该寄存器。否则,先写后读,读到的就是错误(新)数据。
- 写后写(WriteAfterWrite,WAW)相关:表示当前指令写入寄存器后,下一条指令才能写该寄存器。否则,下一条指令在当前指令之前写,将使寄存器的值不是最新值。
解决办法:
-
把遇到数据相关的指令及其后续指令都暂停一至几个时钟周期,直到数据相关问题消失后再继续执行。
可分为硬件阻塞(stall) 和软件插入“NOP”两种方法。
-
数据旁路技术(转发机制):从执行阶段结果出来后送回ALU输入端
-
编译优化:通过编译器调整指令顺序来解决数据相关。
-
控制冒险(控制冲突)
当流水线遇到转移指令和其他改变PC值的指令,必需等待分支处理结果而造成断流时,会引起控制相关。
解决办法:
- 转移指令分支预测。简单预测(永远猜ture或false)、动态预测(根据历史情况动态调整)
- 预取转移成功和不成功两个控制流方向上的目标指令
- 加快和提前形成条件码
- 提高转移方向的猜准率
5.6.4 流水线的性能指标
-
流水线的吞吐率(TP)
吞吐率是指在单位时间内流水线所完成的任务数量,或是输出结果的数量。其公式如下:
T P = n T k TP=\frac {n} {T_k} TP=Tkn
式中, n n n是任务数, T K T_K TK是处理完n个任务所用的总时间。设k为流水段的段数,Δt为时钟周期,在输入流水线任务连续的情况下,一条k段流水线能在k+n-1个时钟周期完成n个任务。流水线吞吐率为
T P = n ( k + n − 1 ) Δ t TP=\frac {n} {(k+n-1)Δt} TP=(k+n−1)Δtn
连续输入的任务数 n → ∞ n\to\infty n→∞时,得到最大吞吐率为 T P m a x = 1 / Δ t TP_{max}=1/Δt TPmax=1/Δt。 -
流水线的加速比(S)
完成同样一批任务,不使用流水线所用的时间与使用流水线所用的时间之比。
流水线加速比的基本公式为
S = T 0 T k S=\frac{T_0}{T_k} S=TkT0
式中, T 0 T_0 T0表示不使用流水线的总时间; T k T_k Tk表示使用流水线的总时间。一条k段流水线完成n个任务所需的时间为 T k = ( k + n − 1 ) Δ t T_k=(k+n-1)Δt Tk=(k+n−1)Δt。顺序执行n个任务时,所需的总时间为 T 0 = k n Δ t T_0=knΔt T0=knΔt。将 T 0 T_0 T0和 T k T_k Tk代入上式,得到流水线加速比为
S = k n Δ t ( k + n − 1 ) Δ t = k n k + n − 1 S=\frac{knΔt}{(k+n-1)Δt}=\frac{kn}{k+n-1} S=(k+n−1)ΔtknΔt=k+n−1kn
连续输入的任务数 n → ∞ n\to\infty n→∞时,得到最大加速比为 S m a x = k S_{max}=k Smax=k。 -
效率
流水线的设备利用率称为流水线的效率。
在时空图上,流水线的效率定义为完成n个任务占用的时空区有效面积与n个任务所用的时间与k个流水段所围成的时空区总面积之比。
5.6.5 高级流水线技术
-
超标量流水线技术
也称动态多发射技术,每个时钟周期内可并发多条独立指令,以并行操作方式将两条或多条指令编译并执行。
-
要配置多个功能部件
-
指令是按顺序发射执行,不能调整指令的执行顺序
-
通过编译优化技术,把可并行执行的指令搭配起来
-
-
超长指令字技术
也称静态多发射技术,由编译程序挖掘出指令间潜在的并行性,将多条能并行操作的指令组合成一条具有多个操作码字段的超长指令字(可达几百位),为此需要采用多个处理部件
-
超流水线技术
在流水线一个时钟周期再划分多个功能段,通过提高流水线主频的方式来提升流水线性能。
但是流水线级数越多,用于流水寄存器的开销就越大,因而流水线级数是有限制的,并不是越多越好。
- 超流水线CPU在流水线充满后,每个时钟周期还是执行一条指令,CPI=1,但其主频更高;
- 多发射流水线CPU每个时钟周期可以处理多条指令,CPI<1,相对而言,多发射流水线成本更高,控制更复杂。
5.7 多处理器的基本概念
5.7.1 SISD、SIMD、MIMD的基本概念
-
单指令流单数据流(SISD)结构
-
特性:在一段时间内仅执行一条指令,按指令流规定的顺序串行执行指令流中的若干条指令。
各指令序列只能并发、不能并行,每条指令处理一两个数据;不是数据级并行技术
-
硬件构成:传统的串行计算机结构,一个处理器和一个存储器;若采用指令流水线,需设置多个功能部件,采用多模块交叉存储器
前面介绍的内容多属于SISD结构
-
-
单指令流多数据流(SIMD)结构
-
特性:一个指令流同时对多个数据流进行处理,一般称为数据级并行技术。
各指令序列只能并发、不能并行,但每条指令可同时处理很多个具有相同特征的数据
-
硬件组成:一个指令控制部件(CU)+多个处理单元/执行单元(如ALU)+多个局部存储器+一个主存储器
每个处理单元虽然执行的都是同一条指令,但是每个单元都有自己的地址寄存器,这样每个单元就都有不同的数据地址。不同处理单元执行的同一条指令所处理的不同数据。
SIMD在使用for循环处理数组时最有效,比如,一条分别对16对数据进行运算的SIMD指令,如果在16个ALU中同时运算,则只需要一次运算时间就能完成运算。
SIMD在使用case或switch语句时效率最低,此时每个执行单元必须根据不同的数据执行不同的操作。
-
-
多指令流单数据流(MISD)结构
多条指令并行执行,处理同一个数据。现实中不存在这种计算机。
-
多指令流多数据流(MIMD)结构
MIMD是指同时执行多条指令分别处理多个不同的数据,MIMD分为多计算机系统和多处理器系统。
- 特性:各指令序列并行执行,分别处理多个不同的数据;是一种线程级并行、甚至是线程级以上并行技术
- 多计算机系统
- 特性:各计算机之间,不能通过存取指令直接访问对方的存储器,只能通过“消息传递”相互传送数据
- 硬件组成:由多台计算机组成,因此拥有多个处理器+多个主存储器;每台计算机拥有各自的私有存储器,物理地址空间相互独立
- 多处理器系统
- 特性:各处理器之间,可以通过存取指令,访问同一个主存储器,可通过主存相互传送数据
- 硬件组成:一台计算机内,包含多个处理器+一个主存储器;多个处理器共享单一的物理地址空间
-
向量处理器:向量处理器是SIMD的变体,是一种实现了**直接操作一维数组(向量)**指令集的CPU,而串行处理器只能处理单一数据集。
- 基本理念:将从存储器中收集的一组数据按顺序放到一组向量寄存器中,然后以流水化的方式对它们依次操作,最后将结果写回寄存器。
- 向量处理器在特定工作环境中极大地提升了性能,擅长对向量型数据并行计算、浮点数运算,常被用于超级计算机中,处理科学研究中巨大运算量
- 硬件组成:多个处理单元,多组“向量寄存器”;主存储器应采用“多个端口同时读取”的交叉多模块存储器;主存储器大小限定了机器的解题规模,因此要有大容量的、集中式的主存储器
5.7.2 硬件多线程的基本概念
为了减少线程切换过程中的开销,便诞生了硬件多线程。在支持硬件多线程的CPU中,必须为每个线程提供单独的通用寄存器组、单独的程序计数器等,线程的切换只需激活选中的寄存器,从而省略了与存储器数据交换的环节,大大减少了线程切换的开销。
硬件多线程有3种实现方式:细粒度多线程、粗粒度多线程和同时多线程(SMT)。
-
细粒度多线程
多个线程之间轮流交叉执行指令,多个线程之间的指令是不相关的,可以乱序并行执行。
处理器能在每个时钟周期切换线程。
-
粗粒度多线程
仅在一个线程出现了较大开销的阻塞时,才切换线程,如Cache 缺失。
阻塞时,新线程的指令开始执行前需要重载流水线,线程切换的开销比细粒度多线程更大。
-
同时多线程
同时多线程(SMT)在同一个时钟周期中,发射多个不同线程中的多条指令执行。
Intel 处理器中的超线程(Hyper-threading)就是同时多线程SMT,即在一个单处理器或单个核中设置了两套线程状态部件,共享高速缓存和功能部件。
细粒度多线程 | 粗粒度多线程 | 同时多线程(SMT) | |
---|---|---|---|
指令发射 | 各个时钟周期,轮流发射多个线程的指令 | 连续几个时钟周期,都发射同一线程的指令序列,流水线阻塞时,切换另一个线程 | 一个时钟周期内,同时发射多个线程的搭令 |
线程切换频率 | 每个时钟周期切换一次线程 | 只有流水线阻塞时才切换一次线程 | |
线程切换代价 | 低 | 高,需要重载流水线 | |
并行性 | 指令级并行,线程间不并行 | 指令级并行,线程间不并行 | 指令级并行,线程级并行 |
三种硬件多线程方式的调度示例:
5.7.3 多核处理器的基本概念
多核处理器是指将多个处理单元集成到单个CPU中,每个处理单元称为一个核(core)。
每个核可以有自己的Cache,也可以共享同一个Cacheo所有核一般都是对称的,并且共享主存储器,因此多核属于共享存储的对称多处理器。下图是不共享Cache的双核CPU结构。
在多核计算机系统中,如要充分发挥硬件的性能,必须采用多线程(或多进程)执行,使得每个核在同一时刻都有线程在执行。
多核上的多个线程是在物理上并行执行的,是真正意义上的并行执行,在同一时刻有多个线程在并行执行。而单核上的多线程是一 种并发的多线程交错执行,实际上在同一时刻只有一个线程在执行。
5.7.4 共享内存多处理器的基本概念
-
定义
具有共享的单一物理地址空间的多处理器被称为共享内存多处理器(SMP)。
处理器通过存储器中的共享变量互相通信,所有处理器都能通过存取指令访问任何存储器的位置。注意,即使这些系统共享同一个物理地址空间,它们仍然可在自己的虚拟地址空间中单独地运行程序。
-
分类
-
统一存储访问(UMA)多处理器
-
定义:每个处理器对所有存储单元的访问时间是大致相同的,即访问时间与哪个处理器提出访存请求及访问哪个字无关。
-
结构:CPU通过前端总线和北桥芯片相连,越来越多的CPU对前端总线的争用使得前端总线成为瓶颈。
-
分类:根据处理器与共享存储器之间的连接方式,分为基于总线、基于交叉开关网络和基于多级交换网络连接等几种处理器。
-
-
非统一存储访问(NUMA)多处理器
-
定义:某些访存请求要比其他的快,具体取决于哪个处理器提出了访问请求以及访问哪个字,这是由于主存被分割并分配给了同一机器上的不同处理器或内存控制器。
-
结构:内存控制器被集成到CPU内部,每个CPU都有独立的内存控制器。每个CPU都独立连接到一部分内存,CPU直连的这部分内存被称为本地内存。
-
分类:处理器中不带高速缓存时,被称为NC-NUMA;处理器中带有一致性高速缓存时,被称为CC-NUMA。
在NUMA架构下,内存的访问出现了本地和远程的区别,访问本地内存明显要快于访问远程内存。
-
-
6 总线
6.1 总线概述
6.1.1 总线的基本概念
-
总线的定义
总线是一组能为多个部件分时共享的公共信息传送线路。
- 分时:指同一时刻只允许有一个部件向总线发送信息,若系统中有多个部件,则它们只能分时地向总线发送信息。
- 共享:指总线上可以挂接多个部件,各个部件之间互相交换的信息都可通过这组线路分时共享,多个部件可同时从总线上接收相同的信息。
-
总线设备
总线上所连接的设备,按其对总线有无控制功能可分为主设备和从设备两种。
- 主设备:指获得总线控制权的设备。
- 从设备:指被主设备访问的设备,它只能响应从主设备发来的各种总线命令。
-
总线特性
总线特性是指机械特性(尺寸、形状)、电气特性(传输方向和有效的电平范围)、功能特性(每根传输线的功能)和时间特性(信号和时序的关系)。
6.1.2 总线的分类
-
片内总线
片内总线是芯片内部的总线,它是CPU芯片内部寄存器与寄存器之间、寄存器与ALU之间的公共连接线。
-
系统总线
系统总线是计算机系统内各功能部件(CPU、主存、I/O接口)之间相互连接的总线。
- 数据总线:用来传输各功能部件之间的数据信息,它是双向传输总线,其位数与机器字长、存储字长有关。
- 地址总线:用来指出数据总线上的源数据或目的数据所在的主存单元或I/O端口的地址,它是单向传输总线,地址总线的位数与主存地址空间的大小有关。
- 控制总线:传输的是控制信息,包括CPU送出的控制命令和主存(或外设)返回CPU的反馈信号。
注意区分数据通路和数据总线:各个功能部件通过数据总线连接形成的数据传输路径称为数据通路。
数据通路表示的是数据流经的路径,而数据总线是承载的媒介。
-
I/O总线
I/O总线主要用于连接中低速的I/O设备,通过I/O接口与系统总线相连接,目的是将低速设备与高速总线分离,以提升总线的系统性能,常见的有USB、PCI总线。
-
通信总线
通信总线是在计算机系统之间或计算机系统与其他系统(如远程通信设备、测试设备)之间传送信息的总线,通信总线也称外部总线。
此外,按时序控制方式可将总线划分为同步总线和异步总线,还可按数据传输格式将总线划分为并行总线和串行总线。
6.1.3 系统总线的结构
-
单总线结构
单总线结构将CPU、主存、I/O设备(通过I/O接口)都挂在一组总线上,允许I/O设备之间、I/O设备与主存之间直接交换信息,如下图所示。
CPU与主存、CPU与外设之间可直接进行信息交换,而无须经过中间设备的干预。
注意,单总线并不是指只有一根信号线,系统总线按传送信息的不同可细分为地址总线、数据总线和控制总线。
- 优点:结构简单,成本低,易于接入新的设备。
- 缺点:带宽低、负载重,多个部件只能争用唯一的总线,且不支持并发传送操作。
-
双总线结构
双总线结构有两条总线:一条是主存总线,用于在CPU、主存和通道之间传送数据;另一条是I/O总线,用于在多个外部设备与通道之间传送数据,如下图所示。
通道:通道是具有特殊功能的处理器,能对I/O设备进行统一管理,通道程序放在主存中。
支持突发(猝发)传送,即送出一个地址,收到多个地址连续的数据
局部总线:连接计算机硬件系统的某一个子系统或部分部件的总线,这样可将一些高速外设,如图形卡,硬盘控制器等状系统总线上卸下而通过局部总线直接挂接
- 优点:将低速I/O设备从单总线上分离出来,实现了存储器总线和I/O总线分离。
- 需要增加通道等硬件设备。
-
三总线结构
三总线结构是在计算机系统各部件之间采用3条各自独立的总线来构成信息通路,这3条总线分别为主存总线、I/O总线和直接内存访问(DMA)总线,如下图所示。
DMA:Direct Memory Access,直接内存访问。
-
优点:提高了I/O设备的性能,使其更快地响应命令,提高系统吞吐量。
-
缺点:系统工作效率较低。
-
-
四总线结构
-
桥接器:用于连接不同的总线,具有数据缓冲、转换和控制功能。
-
靠近CPU的总线速度较快。
-
每级总线的设计遵循总线标准。
-
6.1.4 常见总线标准
总线标准 | 全称 | 工作频率 | 数据位数 | 最大速度 | 特点 |
---|---|---|---|---|---|
ISA | 工业标准体系结构 | 8MHz | 8/16 | 8MB/s | 最早出现在微型计算机 系统总线 |
EISA | 扩展的 ISA | 8MHz | 32 | 32MB/s | 为配合 32 位 CPU 系统总线 兼容ISA |
VESA | 视频电子标准协会 | 33MHz | 32 | 132MB/s | 多媒体PC 局部总线 |
AGP | 加速图形接口 | X1:266MB/s X8:2.1GB/s | 连接主存和图形存储器 局部总线 | ||
PCI | 外部设备互连 | 33MHz | 32/64 | 133MB/s | 高度集成的外围部件、扩充插板 和处理器/存储器系统互连 局部总线 显卡、声卡、网卡 即插即用 与处理器时钟频率无关 的高速外围总线 |
PCI-E | 扩展的PCI | 10GB/s以上 | 最新总线接口标准 串行 | ||
USB | 通用串行总线 | 1280MB/s | 即插即用、热插拔 设备总线 | ||
RS-232 | EIA推荐的总线 | 20kb/s | 串行二进制交换的 数据终端设备(DTE)和 数据通信设备(DCE)之间 串行通信总线 | ||
IDE(ATA) | 集成设备电路 | 100MB/s | IDE接口磁盘驱动器接口类型 硬盘光驱接口 | ||
SATA | 串行高级技术附件 | 600MB/s | 串行硬盘接口 | ||
PCMCIA | 个人计算机存储卡国际协会 | 90MB/s | 泛应用于笔记本电脑 即插即用 便携设备接口 | ||
SCSI | 小型计算机系统接口 | 640MB/s | 计算机和智能设备之间 (硬盘、软驱)系统级接口 智能通用接口 |
6.1.5 总线性能指标
-
总线的传输周期(总线周期)
一次总线操作所需的时间(包括申请阶段、寻址阶段、传输阶段和结束阶段),通常由若干个总线时钟周期构成。
-
总线时钟周期
即机器的时钟周期。计算机有一个统一的时钟,以控制整个计算机的各个部件,总线也要受此时钟的控制。
-
总线工作频率
总线上各种操作的频率,为总线周期的倒数。实际上指一秒内传送几次数据。
-
总线的时钟频率
即机器的时钟频率,为时钟周期的倒数。实际上指一秒内有多少个时钟周期。
-
总线宽度
又称为总线位宽,它是总线上同时能够传输的数据位数,通常是指数据总线的根数,如32根称为32位总线。
-
总线带宽
可理解为总线的数据传输率,即单位时间内总线上可传输数据的位数,通常用每秒钟传送信息的字节数来衡量,单位可用字节/秒(B/s)表示。
-
总线复用
总线复用是指一种信号线在不同的时间传输不同的信息。可以使用较少的线传输更多的信息,从而节省了空间和成本。
-
信号线数
地址总线、数据总线和控制总线3种总线数的总和称为信号线数。
6.2 总线事务和定时
6.2.1 总线事务
从请求总线到完成总线使用的操作序列称为总线事务,它是在一个总线周期中发生的一系列活动。典型的总线事务包括请求操作、仲裁操作、地址传输、数据传输和总线释放。
- 请求阶段。主设备(CPU或DMA)发出总线传输请求,并且获得总线控制权。
- 仲裁阶段。总线仲裁机构决定将下一个传输周期的总线使用权授予某个申请者。
- 寻址阶段。主设备通过总线给出要访问的从设备地址及有关命令,启动从模块。
- 传输阶段。主模块和从模块进行数据交换,可单向或双向进行数据传送。
- 释放阶段。主模块的有关信息均从系统总线上撤除,让出总线使用权。
突发(猝发)传送方式能够进行连续成组数据的传送,其寻址阶段发送的是连续数据单元的首地址,在传输阶段传送多个连续单元的数据,每个时钟周期可以传送一个字长的信息,但是不释放总线,直到一组数据全部传送完毕后,再释放总线。
6.2.2 同步定时方式
-
定义
所谓同步定时方式,是指系统采用一个统一的时钟信号来协调发送和接收双方的传送定时关系。
时钟产生相等的时间间隔,每个间隔构成一个总线周期。在一个总线周期中,发送方和接收方可以进行一次数据传送。因为采用统一的时钟,每个部件或设备发送或接收信息都在固定的总线传送周期中,一个总线的传送周期结束,下一个总线的传送周期开始。
-
优点:传送速度快,具有较高的传输速率;总线控制逻辑简单。
-
缺点:主从设备属于强制性同步:不能及时进行数据通信的有效性检验,可靠性较差。
6.2.3 异步定时方式
- 定义:
在异步定时方式中,没有统一的时钟,也没有固定的时间间隔,完全依靠传送双方相互制约的“握手”信号来实现定时控制。
通常,把交换信息的两个部件或设备分为主设备和从设备,主设备提出交换信息的“请求”信号,经接口传送到从设备;从设备接到主设备的请求后,通过接口向主设备发出“回答”信号。
根据“请求”和“回答”信号的撤销是否互锁,异步定时方式又分为以下3种类型。
- 不互锁方式。
- 主设备发出“请求”信号后,不必等到接到从设备的“回答”信号,而是经过一段时间便撤销“请求”信号。
- 而从设备在接到“请求”信号后,发出“回答”信号并经过一段时间后自动撤销“回答”信号。双方不存在互锁关系,如图(a)所示。
- 速度最快可靠性最差
- 半互锁方式。
- 主设备发出“请求”信号后,必须在接到从设备的“回答”信号后,才撤销“请求”信号,有互锁的关系。
- 而从设备在接到“请求”信号后,发出“回答”信号,但不必等待获知主设备的“请求”信号已经撒销,而是隔一段时间后自动撤销“回答”信号,不存在互锁关系。半互锁方式如图(b)所示。
- 全互锁方式。
- 主设备发出“请求”信号后,必须在从设备“回答”后才撤销“请求”信号;
- 从设备发出“回答”信号后,必须在获知主设备“请求”信号已撤销后,再撤销其“回答”信号。双方存在互锁关系,如图©所示。
- 最可靠速度最慢
-
优点:总线周期长度可变,能保证两个工作速度相差很大的部件或设备之间可靠地进行信息交换,自动适应时间的配合。
-
缺点:比同步控制方式稍复杂一些,速度比同步定时方式慢。
7 输入/输出系统
7.1 I/O系统基本概念
7.1.1 输入/输出系统
输入/输出是以主机为中心而言的,将信息从外部设备传送到主机称为输入,反之称为输出。输入/输出系统解决的主要问题是对各种形式的信息进行输入和输出的控制。
-
基本概念
- 外部设备。包括输入/输出设备及通过输入/输出接口才能访问的外存储设备
- 接口。在各个外设与主机之间传输数据时进行各种协调工作的逻辑部件。协调包括传输过程中速度的匹配、电平和格式转换等。
- 输入设备。用于向计算机系统输入命令和文本、数据等信息的部件。键盘和鼠标是最基本的输入设备。
- 输出设备。用于将计算机系统中的信息输出到计算机外部进行显示、交换等的部件。显示器和打印机是最基本的输出设备
- 外存设备。指除计算机内存及CPU缓存等外的存储器。如,硬磁盘、光盘等
-
I/O系统由软件和硬件两部分构成
- I/O软件。包括驱动程序、用户程序、管理程序、升级补丁等。通常采用IO指令和通道指令实现CPU与I/O设备的信息交换
- I/O硬件。包括外部设备、设备控制器和接口、I/O总线等。通过设备控制器来控制IO设备的具体动作;通过I/O接口与主机(总线)相连
7.1.2 I/O控制方式
输入/输出系统中,经常需要进行大量的数据传输,而传输过程中有各种不同的I/O控制方式,基本的控制方式主要有以下4种。
- 1)程序查询方式。由CPU通过程序不断查询i/O设备是否已做好准备,从而控制I/O设备与主机交换信息。
- 2)程序中断方式。只在I/O设备准备就绪并向CPU发出中断请求时才予以响应。
- 3)DMA方式。主存和IO设备之间有一条直接数据通路,当主存和I/O设备交换信息时无须调用中断服务程序
- 4)通道方式。在系统中设有通道控制部件,每个通道都挂接若干外设,主机在执行I/O命令时,只需启动有关通道,通道将执行通道程序,从而完成I/O操作
其中,方式1)和方式2)主要用于数据传输率较低的外部设备,方式3)和方式4)主要用于数据传输率较高的设备。
7.1.3 外部设备
-
输入设备
- 键盘:键盘是最常用的输入设备,通过它可发出命令或输入数据
- 鼠标:鼠标是常用的定位输入设备,它把用户的操作与计算机屏幕上的位置信息相联系。
-
输出设备
-
显示器:按所用的显示器件分类,有阴极射线管(CRT)显示器、液晶显示器(LCD)、发光二极管(LED)显示器等。显示器属于用点阵方式运行的设备,有以下主要参数:
-
屏幕大小:以对角线长度表示,常用的有12~29英寸等.
-
分辨率:能表示的像素个数,屏幕上的每个光点就是一个像素,以宽和高的像素数的乘积表示,如800×600、1024x768和1280×1024等。
-
灰度级:指黑白显示器中所显示的像素点的亮暗差别,在彩色显示器中则表现为颜色的不同,灰度级越多,图像层次越清楚、逼真,典型的有8位(256级)、16位等
-
刷新:光点只能保持极短的时间便会消失,为此必须在光点消失之前再重新扫描显示遍,这个过程称为刷新。
-
刷新频率:指单位时间内扫描整个屏幕内容的次数。按照人的视觉生理,刷新频率大于30Hz时才不会感到闪烁,通常显示器的刷新频率为60120Hz
-
显示存储器(VRAM):也称刷新存储器,为了不断提高剧新图像的信号,必须把一帧图像信息存储在刷新存储器中。其存储容量由图像分辨率和灰度级决定,分辨率越高,灰度级越多,刷新存储器容量越大。
V R A M 容量 = 分辨率 × 灰度级位数 V R A M 带宽 = 分辨率 × 灰度级位数 × 帧频 VRAM容量=分辨率×灰度级位数\\ VRAM带宽=分辨率×灰度级位数×帧频 VRAM容量=分辨率×灰度级位数VRAM带宽=分辨率×灰度级位数×帧频
-
-
打印机:用于将计算机的处理结果打印在相关介质上。按工作方式,打印机可分为点阵打印机、针式打印机、喷墨式打印机、激光打印机等
- 针式打印机。针式打印机擅长“多层复写打印”,实现各种票据或蜡纸等的打印。其工作原理简单,造价低廉,耗材(色带)便宜,但打印分辨率和打印速度不够高。
- 喷墨式打印机。彩色喷墨打印机基于三基色原理,即分别喷射3种颜色的墨滴,按一定的比例混合出所要求的颜色。喷墨式打印机可实现高质量彩色打印。
- 激光打印机。计算机输出的二进制信息,经过调制后的激光束扫描,在感光鼓上形成潜像,再经过显影、转印和定影,在纸上得到所需的字符或图像。激光打印机打印质量高、速度快、处理能力强,它是将激光技术和电子显像技术相结合的产物
-
-
外部存储器(辅存)
- 磁表面存储器:所谓“磁表面存储",是指把某些磁性材料薄薄地涂在金属铝或塑料表面上作为载磁体来存储信息。磁盘存储器、磁带存储器和磁鼓存储器均属于磁表面存储器。
- 固态硬盘(SSD):微小型高档笔记本电脑采用高性能Flash存储器作为硬盘来记录数据,这种“硬盘”称为固态硬盘(SSD)。固态硬盘除需要Flash存储器外,还需要其他硬件和软件的支持。
- 光盘存储器:光盘存储器是利用光学原理读/写信息的存储装置,它采用聚焦激光束对盘式介质以非接触方式记录信息。完整的光盘存储系统由光盘片、光盘驱动器、光盘控制器等组成。
7.2 I/O接口
I/O接口(I/O控制器)是主机和外设之间的交接界面,通过接口可以实现主机和外设之间的信息交换。主机和外设具有各自的工作特点,它们在信息形式和工作速度上具有很大的差异,接口正是为了解决这些差异而设置的。
7.2.1 I/O接口的功能
- 进行地址译码和设备选择。CPU送来选择外设的地址码后,接口必须对地址进行译码以产生设备选择信息,使主机能和指定外设交换信息。
- 实现主机和外设的通信联络控制。解决主机与外设时序配合问题,协调不同工作速度的外设和主机之间交换信息,以保证整个计算机系统能统一、协调地工作。
- 实现数据缓冲。CPU与外设之间的速度往往不匹配,为消除速度差异,接口必须设置数据缓冲寄存器,用于数据的暂存,以避免因速度不一致而丢失数据。
- 信号格式的转换。外设与主机两者的电平、数据格式都可能存在差异,接口应提供计算机与外设的信号格式的转换功能,如电平转换、并/串或串/并转换、模/数或数/模转换等。
- 传送控制命令和状态信息。CPU要启动某一外设时,通过接口中的命令寄存器向外设发出启动命令;外设准备就绪时,则将“准备好”状态信息送回接口中的状态寄存器,并反馈给CPU。外设向CPU提出中断请求时,CPU也应有相应的响应信号反锁给外设。
7.2.2 I/O接口的基本结构
如图所示,I/O接口在主机侧通过I/O总线与内存、CPU相连。
通过数据总线,在数据缓冲寄存器与内存或CPU的寄存器之间进行数据传送。同时接口和设备的状态信息被记录在状态寄存器中,通过数据线将状态信息送到CPU。CPU对外设的控制命令也通过数据线传送,一般将其送到I/O接口的控制寄存器。状态寄存器和控制寄存器在传送方向上是相反的。
-
内部结构
- 数据缓冲寄存器(DBR):暂存即将输入输出的数据;主机和外设的速度匹配。
- 状态/控制寄存器:命令字:CPU对设备发出的具体命令;状态字:设备的状态信息,供CPU检查。
- 串-并转换机构:数据格式的转换。
- I/O控制逻辑:根据命令字向设备发出控制信号。
- 地址译码逻辑:将地址信号映射到指定I/O端口。
-
内部接口(主机侧)
内部接口,内部接口与系统总线相连,实质上是与内存、CPU相连。
- 数据线:读写数据、状态字、控制字、中断类型号
- 地址线:指明I/O端口
- 控制线:读/写I/O端口的信号、中断请求信号
-
外部接口(设备侧)
外部接口通过接口电缆与外设相连,外部接口的数据传输可能是串行方式,因此I/O接口需具有串/并转换功能。
-
工作原理
①发命令:发送命令字到I/O控制寄存器,向设备发送命令(需要驱动程序的协助)
②读状态:从状态寄存器读取状态字,获得设备或I/O控制器的状态信息
③读/写数据:从数据缓冲寄存器发送或读取数据,完成主机与外设的数据交换
7.2.3 I/O接口的类型
-
按数据传送方式
- 并行接口:一字节或一个字的所有位同时传送。
- 串行接口:一位一位地传送。
这里所说的数据传送方式指的是外设和接口一侧的传送方式。
-
按主机访问I/O设备的控制方式
- 程序查询接口
- 中断接口
- DMA接口
-
按功能选择的灵活性
- 可编程接口
- 不可编程接口
7.2.4 I/O端口及其编址
-
接口和端口
I/O端口是指接口电路中可以被CPU直接访问的寄在器。
接口=端口(数据端口:读&写、控制端口:写、状态端口:读)+控制逻辑
I/O端口要想能够被CPU访问,就必须要对各个端口进行编号,每个端口对应一个端口地址。
-
端口编址方式
-
统一编址:又称存储器映射方式,是指把I/O端口当作存储器的单元进行地址分配,这种方式CPU不需要设置专门的I/O指令,用统一的访存指令就可以访问I/O端口。
- 优点:不需要专门的输入/输出指令,可使CPU访问I/O的操作更灵活、更方便,还可使端口有较大的编址空间。
- 缺点:端口占用存储器地址,使内存容量变小,而且利用存储器编址的I/O设备进行数据输入/输出操作,执行速度较慢
靠不同的地址码区分内存和I/O设备,I/O地址要求相对固定在地址的某部分。
-
独立编址:又称I/O映射方式,I/O端口的地址空间与主存地址空间是两个独立的地址空间,因而无法从地址码的形式上区分,需要设置专门的I/O指令来访问I/O端口。
- 优点:输入输出指令与存储器指令有明显区别,程序编制清晰,便于理解。
- 缺点:输入输出指令少,一般只能对端口进行传送操作,尤其需要CPU提供存储器读/写、I/O设备读写两组控制信号,增加了控制的复杂性。
靠不同的指令区分内存和I/O设备。
-
7.3 I/O方式
输入/输出系统实现主机与I/O设备之间的数据传送,可以采用不同的控制方式。常用的I/O方式有程序查询、程序中断、DMA和通道等,其中前两种方式更依赖于CPU中程序指令的执行。
7.3.1 程序查询方式
信息交换的控制完全由CPU执行程序实现,程序查询方式接口中设置一个数据缓冲寄存器(数据端口)和一个设备状态寄存器(状态端口)。
-
查询方式:
CPU“忙等”慢速设备完成工作,二者串行工作。CPU查询速率应比输入速率高;不然数据丢失。
CPU不断轮询检查I/O控制器中的“状态寄存器”,检测到状态为“已完成”之后再从数据寄存器取出输入数据。
-
工作流程
- ①CPU执行初始化程序,并预置传送参数。
- ②向I/O接口发出命令字,启动I/O设备。
- ③从外设接口读取其状态信息。
- ④CPU不断查询I/O设备状态,直到外设准备就绪。
- ⑤传送一次数据。
- ⑥修改地址和计数器参数。
- ⑦判断传送是否结束,若未结束转第③步,直到计数器为0。
-
特点
-
在这种控制方式下,CPU一旦启动I/O,就必须停止现行程序的运行,并在现行程序中插入一段程序。
程序查询方式的主要特点是CPU有“踏步”等待现象,CPU与I/O串行工作。
-
优点:这种方式的接口设计简单、设备量少,
-
缺点:CPU在信息传送过程中要花费很多时间来查询和等待,而且在一段时间内只能和一台外设交换信息,效率大大降低。
-
7.3.2 程序中断方式
-
程序中断的基本概念
设备准备数据时,CPU继续工作。设备准备好之后向CPU发出中断请求,CPU在指令周期的末位检查中断并做出中断响应(执行中断处理程序)。
中断功能:
-
①实现CPU与IO设备的并行工作。
-
②处理硬件故障和软件错误。
-
③实现人机交互,用户干预机器需要用到中断系统。
-
④实现多道程序、分时操作,多道程序的切换需借助于中断系统。
-
⑤实时处理需要借助中断系统来实现快速响应。
-
⑥实现应用程序和操作系统(管态程序)的切换,称为“软中断"。
-
⑦多处理器系统中各处理器之间的信息交流和任务切换。
程序中断思想:
CPU在程序中安排好在某个时机启动某台外设,然后CPU继续执行当前的程序,不需要像查询方式那样一直等待外设准备就绪。一旦外设完成数据传送的准备工作,就主动向CPU发出中断请求,请求CPU为自己服务。在可以响应中断的条件下,CPU暂时中止正在执行的程序,转去执行中断服务程序为外设服务,在中断服务程序中完成一次主机与外设之间的数据传送,传送完成后,CPU返回原来的程序,如下图所示。
-
-
中断的分类
- 内中断:CPU内部请求中断,与当前执行的指令有关
- 陷入:自愿中断,如系统调用时使用的访管指令
- 故障:如缺页
- 异常:如整数除0
- 外中断:CPU外部请求中断,与当前执行的指令无关。
- 可屏蔽中断:关中断时不会被响应
- 不可屏蔽中断:关中断时也会被响应(如:掉电)
- 内中断:CPU内部请求中断,与当前执行的指令有关
-
程序中断的工作流程
-
中断请求
中断源向CPU发送中断请求信号。
-
中断源:中断源是请求CPU中断的设备或事件,一台计算机允许有多个中断源。
-
中断请求标记:每个中断源向CPU发出中断请求的时间是随机的。为记录中断事件并区分不同的中断源,中断系统需对每个中断源设置中断请求标记触发器,当其状态为“1”时,表示中断源有请求。这些触发器可组成中断请求标记寄存器,该寄存器可集中在CPU中,也可分散在各个中断源中。
-
中断分类
- 可屏蔽中断:通过INTR线发出的是可屏蔽中断,可屏蔽中断的优先级最低,在关中断模式下不会被响应。
- 不可屏蔽中断:通过NMI线发出的是不可屏蔽中断,不可屏蔽中断用于处理紧急和重要的事件,如时钟中断、电源掉电等,其优先级最高,其次是内部异常,即使在关中断模式下也会被响。
-
-
中断响应判优
-
中断响应优先级:中断响应优先级是指CPU响应中断请求的先后顺序。
由于许多中断源提出中断请求的时间都是随机的,因此当多个中断源同时提出请求时,需通过中断判优逻辑来确定响应哪个中断源的请求。
-
中断判优的实现:
- 硬件实现是通过硬件排队器实现的,它既可以设置在CPU中,也可以分散在各个中断源中;
- 软件实现是通过查询程序实现的。
-
中断优先级设置
- ①不可屏蔽中断>内部异常>可屏蔽中断;
- ②内部异常中,硬件故障>软件中断;
- ③DMA中断请求>I/O设备传送的中断请求;
- ④在I/O传送类中断请求中,高速设备>低速设备,输入设备>输出设备,实时设备>普通设备。
-
-
CPU响应中断的条件
- ①中断源有中断请求。
- ②CPU允许中断及开中断(异常和不可屏蔽中断不受此限制)。
- ③一条指令执行完毕(异常不受此限制),且没有更紧迫的任务。
-
中断响应过程
-
中断隐指令:中断隐指令并不是指令系统中的一条真正的指令,只是一种虚拟的说法,本质上是硬件的一系列自动操作。它所完成的操作如下:
-
关中断。CPU响应中断后,首先要保护程序的断点和现场信息,在保护断点和现场的过程中,CPU不能响应更高级中断源的中断请求。否则,若断点或现场保存不完整,在中断服务程序结束后,就不能正确地恢复并继续执行现行程序。
-
保存断点。为保证在中断服务程序执行完后能正确地返回到原来的程序,必须将原程序的断点(指令无法直接读取的PC和PSW的内容)保存在栈或特定寄存器中。
注意异常和中断的差异:异常指令通常并没有执行成功,异常处理后要重新执行,所以其断点是当前指令的地址。中断的断点则是下一条指令的地址。
-
引出中断服务程序。识别中断源,将对应的服务程序入口地址送入程序计数器PC。
有两种方法识别中断源:硬件向量法和软件查询法。
-
-
-
中断向量
中断识别分为向量中断和软件查询法两种。
- 中断向量:每个中断都有一个唯一的类型号,每个中断类型号都对应一个中断服务程序,每个中断服务程序都有一个入口地址,CPU必须找到入口地址,即中断向量。
- 中断向量表:把系统中的全部中断向量集中存放到存储器的某个区域内,这个存放中断向量的存储区就称为中断向量表。
- 中断向量法:由硬件产生向量地址,再由向量地址找到入口地址。
-
中断处理过程
中断处理流程如图所示。
中断处理流程如下:
-
①关中断。
-
②保存断点。
-
③中断服务程序寻址。
-
④保存现场和屏蔽字。进入中断服务程序后首先要保存现场和中断屏蔽字,现场信息是指用户可见的工作寄存器的内容,它存放着程序执行到断点处的现行值。
注意:现场和断点,这两类信息都不能被中断服务程序破坏。现场信息因为用指令可直接访问,所以通常在中断服务程序中通过指令把它们保存到栈中,即由软件实现;而断点信息由CPU在中断响应时自动保存到栈或指定的寄存器中,即由硬件实现。
-
⑤开中断。允许更高级中断请求得到响应,实现中断嵌套。
-
⑥执行中断服务程序。这是中断请求的目的。
-
⑦关中断。保证在恢复现场和屏蔽字时不被中断。
-
⑧恢复现场和屏蔽字。将现场和屏蔽字恢复到原来的状态。
-
⑨开中断、中断返回。中断服务程序的最后一条指令通常是一条中断返回指令,使其返回到原程序的断点处,以便继续执行原程序。
其中,①~③由中断隐指令(硬件自动)完成;④~⑨由中断服务程序完成。
-
-
-
多重中断和中断屏蔽技术
- 单重中断:若CPU在执行中断服务程序的过程中,又出现了新的更高优先级的中断请求,而CPU对新的中断请求不予响应,则这种中断称为单重中断,如图(a)所示。
- 多重中断:若CPU暂停现行的中断服务程序,转去处理新的中断请求,则这种中断称为多重中断,又称中断嵌套,如图(b)所示。
CPU要具备多重中断的功能,必须满足下列条件:
- ①在中断服务程序中提前设置开中断指令。
- ②优先级别高的中断源有权中断优先级别低的中断源。
中断屏蔽技术:
每个中断源都有一个屏蔽触发器,1表示屏蔽该中断源的请求,0表示可以正常申请,所有屏蔽触发器组合在一起,便构成一个屏蔽字寄存器,屏蔽字寄存器的内容称为屏蔽字。
屏蔽字设置的规律:
- 一般用’1’表示屏蔽,0表示正常申请。
- 每个中断源对应一个屏蔽字(在处理该中断源的中断服务程序时,屏蔽寄存器中的内容为该中断源对应的屏蔽字)。
- 屏蔽字中1越多,优先级越高。每个屏蔽字中至少有一个’1’(至少要能屏蔽自身的中断)。
例:中断处理优先级D>A>C>B;屏蔽字如下表所示。
7.3.3 DMA方式
DMA方式是一种完全由硬件进行成组信息传送的控制方式,它具有程序中断方式的优点,即在数据准备阶段,CPU与外设并行工作。
DMA方式在外设与内存之间开辟一条“直接数据通道”,信息传送不再经过CPU,降低了CPU在传送数据时的开销,因此称为直接存储器存取方式。
这种方式适用于磁盘、显卡、声卡、网卡等高速设备大批量数据的传送,它的硬件开销比较大。在DMA方式中,中断的作用仅限于故障和正常传送结束时的处理。
-
DMA方式的特点
主存和DMA接口之间有一条直接数据通路。由于DMA方式传送数据不需要经过CPU,因此不必中断现行程序,I/O与主机并行工作,程序和传送并行工作。
- ①它使主存与CPU的固定联系脱钩,主存既可被CPU访问,又可被外设访问。
- ②在数据块传送时,主存地址的确定、传送数据的计数等都由硬件电路直接实现。
- ③主存中要开辟专用缓冲区,及时供给和接收外设的数据。
- ④DMA传送速度快,CPU和外设并行工作,提高了系统效率。
- ⑤DMA在传送开始前要通过程序进行预处理,结束后要通过中断方式进行后处理。
-
DMA控制器主要功能
CPU向DMA控制器指明要输入还是输出;要传送多少个数据;数据在主存、外设中的地址。
- 传送前
- 1)接受外设发出的DMA请求(外设传送一个字的请求),并向CPU发出总线请求。
- 2)CPU响应此总线请求,发出总线响应信号,接管总线控制权,进入DMA操作周期。
- 传送时
- 3)确定传送数据的主存单元地址及长度,并能自动修改主存地址计数和传送长度计数。
- 4)规定数据在主存和外设间的传送方向,发出读写等控制信号,执行数据传送操作。
- 传送后
- 5)向CPU报告DMA操作的结束。
- 传送前
-
DMA控制器的组成
下图为DMA控制器结构图。
- 主存地址计数器:简称AR,存放要交换数据的主存地址
- 传送长度计数器:简称WC,用来记录传送数据的长度,计数溢出时,数据即传送完毕,自动发中断请求信号。
- 数据缓冲寄存器:暂存每次传送的数据。
- DMA请求触发器:每当I/O设备准备好数据后给出一个控制信号,使DMA请求触发器置位。
- 控制/状态逻辑:由控制和时序电路及状态标志组成,用于指定传送方向,修改传送参数,并对DMA请求信号和CPU响应信号进行协调和同步。
- 中断机构:数据传送完毕后触发中断机构,提出中断请求。
在DMA传送过程中,DMA控制器将接管CPU的地址总线、数据总线和控制总线,CPU的 主存控制信号被禁止使用。而当DMA传送结束后,将恢复CPU的一切权利并开始执行其操作。
-
DMA的传送方式
主存和I/O设备之间交换信息时,不通过CPUo但当I/O设备和CPU同时访问主存时,可能发生冲突,为了有效地使用主存,DMA控制器与CPU通常采用以下3种方式使用主存:
- 停止CPU访存:需要数据传送时,停止CPU访存,总线控制权交给DMA控制器
- 交替访存:将CPU周期分为DMA访存和CPU访存两个部分
- 周期挪用(周期窃取):I/O设备需要访存时,挪用一个或几个存取周期
- CPU此时不访存(不冲突)
- CPU正在访存(存取周期结束让出总线)
- CPU与DMA同时请求访存(I/O访存优先)
-
DMA的传送过程
-
预处理:CPU完成寄存器初值设置等准备工作
- 首先,CPU执行几条I/O指令,用以测试I/O设备状态,初始化DMA控制器中的有关寄存器、设置传送方向、启动该设备等。
- 然后,CPU继续执行原来的程序,直到I/O设备准备好发送的数据(输入情况)或接收的数据(输出情况)时,I/O设备向DMA控制器发送DMA请求,
- 再由DMA控制器向CPU发送总线请求(有时将这两个过程统称为DMA请求),用以传输数据。
-
数据传送:CPU继续执行主程序,DMA控制器完成数据传送
-
DMA的数据传输可以以单字节(或字)为基本单位,也可以以数据块为基本单位。
-
对于以数据块为单位的传送(如硬盘),DMA占用总线后的数据输入和输出操作都是通过循环来实现的。
-
需要指出的是,这一循环也是由DMA控制器(而非通过CPU执行程序)实现的,即数据传送阶段完全由DMA(硬件)控制。
-
-
后处理:CPU执行中断服务程序做DMA结束处理
- 包括校验送入主存的数据是否正确、测试传送过程中是否出错(错误则转诊断程序)及决定是否继续使用DMA传送其他数据等。
-
-
DMA方式和中断方式的区别
DMA方式和中断方式的重要区别如下:
- ①中断方式是程序的切换,需要保护和恢复现场:而DMA方式不中断现行程序,无需保护现场,除了预处理和后处理,其他时候不占用任何CPU资源。
- ②对中断请求的响应只能发生在每条指令执行结束时(执行周期后):而对DMA请求的响应可以发生在任意一个机器周期结束时(取指、间址、执行周期后均可)。
- ③中断传送过程需要CPU的干预;而DMA传送过程不需要CPU的干预,因此数据传输率非常高,适合于高速外设的成组数据传送。
- ④DMA请求的优先级高于中断请求。
- ⑤中断方式具有处理异常事件的能力,而DMA方式仅局限于大批数据的传送。
- ⑥从数据传送来看,中断方式靠程序传送,DMA方式靠硬件传送。
中断 DMA 数据传送 程序控制
程序的切换→保存和恢复现场硬件控制
CPU只需进行预处理和后处理中断请求 传送数据 后处理 响应 指令执行周期结束后响应中断 每个机器周期结束均可,总线空闲时
即可响应DMA请求场景 CPU控制,低速设备 DMA控制器控制,高速设备 优先级 优先级低于DMA 优先级高于中断 异常处理 能处理异常事件 仅传送数据