计算机组成原理
第一章 计算机系统概述
1.1计算机发展历程
- 低电平表示二进制0
- 高电平表示二进制1
- 金属针脚用来接受和发送电信号二进制数,每个二进制数位称为1bit
- 计算机性能的好坏取决于软硬件功能的总和
- 机器字长:计算机一次整数运算所能处理的二进制位数
- 摩尔定律:集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,整体性能也将提升一倍
1.2计算机硬件的基本组成
早期冯诺依曼机的结构
特点
- 采用存储程序的工作方式
- 将指令以二进制代码的形式事先输入计算机的主储存器(内存),然后按其在存储器中的首地址执行程序的第一条指令,以后就按该程序的规定顺序执行其他指令,直至程序执行结束
- 得以实现自动化地执行代码
- 计算机由五大部件组成
- 运算器
- 控制器
- 存储器
- I/O设备
- 指令和数据以同等地位存于存储器,可按地址寻访
- CPU区分指令和数据的依据是二者访问阶段的不同
- 指令和数据用二进制表示
- 指令由操作码(操作类型)和地址码(操作数据的地址)组成
- 以运算器为中心
- 输入/输出设备与存储器之间的数据传送通过运算器完成
- 导致数据计算效率的降低
- 输入/输出设备与存储器之间的数据传送通过运算器完成
现代计算机的结构
特点
- 以存储器为中心
- CPU=运算器+控制器
- 指令存放于控制器当中,由控制器来解析并且发出相应的控制信号
- 注:辅存主要指机械硬盘固态硬盘等,不属于主机内容而属于I/O设备,例如我们手机里的APP平时储存在辅存里面,只有使用的时候才会把辅存里边的app相关的程序数据代码读到主存里边
1.3各个硬件的工作原理
主存储器
基本组成
-
存储体
-
用于存放数据,由一系列的存储元件构成,用于存放零和一
-
数据在存储体内按地址存储
- 存储单元:每个存储单元存放一串二进制代码
- 存储字:存储单元中二进制代码的组合
- 存储字长:存储单元中二进制代码的位数
- 存储元:即存储二进制的电子元件,每个存储元可存1bit(电容存储)
-
-
寄存器
- 注:现在的计算机通常把MAR、MDR也集成在CPU内
- MAR(存储地址寄存器)
- MAR位数反映了存储单元的个数(最多支持多少个)
- MDR(存储数据寄存器)
- MDR位数=存储字长(bits)=每个存储单元的大小
- 读取
- 写入
运算器
用于实现算术运算(加减乘除)、逻辑运算(与或非)
基本组成
- ACC:累加器,用于存放操作数或者运算结果
- MQ:乘商寄存器,在乘、除运算时,用于存放操作数或者运算结果
- X:通用的操作数寄存器,用于存放操作数
ALU:算数逻辑单元,通过复杂的电路实现算数运算、逻辑运算,上面为数据储存结构
控制器
基本组成
-
CU:控制单元,分析指令,给出控制信号
-
IR:指令寄存器,存放当前执行的指令
-
PC:程序计数器,存放下一条指令地址,有自动加1的功能
-
完成一条指令的流程:
- 取指令 PC
- 分析指令 IR
- 执行指令 CU
计算机的工作过程
- 过程演示
- 总结
1.4计算机系统的多级层级结构
计算机系统的层次结构
1.5计算机的性能指标
存储器的性能指标
-
存储器的容量
-
总容量=存储单元个数*存储字长
=存储单元个数*存储字长/8
-
CPU的性能指标
-
CPU主频:CPU内数字脉冲信号震荡的频率,表示的是每秒钟会有多少个数字脉冲,即会出多少个时钟周期
- 如10Hz可能是每秒钟有10个脉冲信号
- 平均CPI=∑各指令CPIx指令混合比
- 同一套指令集意味着指令总数相同
系统整体的性能指标
-
数据通路带宽:数据总线一次所能并行传送信息的位数(各硬件部件通过数据总线传输数据)
-
吞吐量:指系统在单位时间内处理请求的数量
- 它取决于信息能多快地输入内存,CPU能多快地取指令,数据能多快地从内存取出或存入,以及所得结果能多快地从内存送给一台外部设备。这些步骤中的每一步都关系到主存,因此,系统吞吐量主要取决于主存的存取周期。(了解即可)
-
响应时间:指从用户向计算机发送一个请求,到系统对该请求做出相应并获得它所需要的结果的等待时间
- 通常包括CPU时间(运行一个程序所花费的时间)与等待时间(用于磁盘访问、存储器访问、I/O操作、操作系统开销等时间)(简单了解即可)
系统整体的性能指标(动态测试)
- 基准程序(跑分软件)是用来测量计算机处理速度的一种实用程序,以便于被测量的计算机性能可以与运行相同程序的其他计算机性能进行比较
提高计算机性能的主要途径
- 提高时钟频率(流水线)
- 优化处理其中数据通路的结构以降低CPI(单周期/多周期/流水线)
- 采用编译优化措施来减少指令条数或降低指令复杂度(指令系统)
第二章 数据的表示和运算
-
数值数据和非数值数据
- 数值数据是指能在数轴上找到点的数据
- 定点数、浮点数
- 非数值数据是指字母、汉字等
- char,string
- 数值数据是指能在数轴上找到点的数据
-
数值数据表示的三要素
- 进位计数值
- 定、浮点表示
- 如何用二进制编码
- 要确定一个数值数据的值必须先确定这三个要素
-
整数都采用补码来表示
- 但浮点数的尾数用原码定点小数表示
-
补码特性:模运算
- 在一个模运算系统中,一个数与它除以模以后的余数等价
- 一个负数的补码等于模减去该负数的绝对值
- 一个正数的补码等于模加上它本身即等于原码
- 任何一个数用n位1来减相当于各位取反,末位+1
- 对于某一确定的模,某数减去小于模的另一个数,总可以用该数加上另一个数符数的补码来替代
-
2的16次方之内要牢记
-
变形(模4)补码:双符号,用于存放可溢出的中间结果
-
无符号数0扩展,带符号整数符号扩展
-
无符号数和带符号数运算一般转化为无符号数
-
因为原码是对称的,所以尾数的表示范围关于原点对称
2.1数制与编码
2.1.1 进位计数制
r进制计数法
二进制与八进制、十六进制互相转换
- 二到八
- 二到十六
- 八到二
- 十六到二
十进制转化为任意进制
- 整数部分
- 小数部分
- 拼凑法转化为二进制
2.1.2 BCD(用二进制编码的十进制数)码
- 四个二进制位表示一个十进制位
- 8421码映射关系(有权码)
- 余3码(无权码)
- 2421码(有权码)
0-4的首位一定是0,5-9的首位一定是1
2.1.3 无符号整数的表示和运算
无符号整数的表示
无符号整数的加法运算
无符号整数的减法运算
2.1.4 带符号整数的表示和运算 原反补
原码表示(Sign and magnitude)
原码→反码→补码的转换(机算)
原码、补码快速转换技巧(手算)
补码的加法运算
- 注:由于补码数值不能解读为位权,因此真值需要转换为原码再去找真值
补码的减法运算
- 机算
- 手算
- 找到第一个1,然后1的左边的所有位数包括符号位在内取反,右边保持不变
对比:无符号整数的减法运算
- 无论是带符号整数还是无符号整数的减法,都是被减数不变,减数全部位按位取反、末位+1,减法变加法
- 计算机内部,所有带符号整数的加减法都要先转化为补码(当然C语言的带符号整数都是用补码来表示的)
2.1.5 原反补码的特性对比
各种码的基本特性总结
2.1.6 移码
- 移码:补码的基础上将符号位取反。注意:移码只能用于表示整数。
2.1.7 定点小数
- 定点小数的符号位后面常常用“.”隔开,而定点整数的符号位后面常常用“,”隔开
定点小数原/反/补码的转换
定点小数的加/减运算
定点小数vs定点整数
小数补码的加法运算
小数补码的减法运算
2.2 运算方法和运算电路
2.2.0 奇偶校验码
校验原理简介
奇偶校验码
- 奇偶校验码的缺点:只能发现奇数个位发生传输错误,不能发现偶数个位发生传输错误
偶校验码的硬件实现
2.2.1 电路的基本原理、加法器设计
算术逻辑单元(ALU)
- 控制信号是由控制单元cu发出的
- M用来表示做的是逻辑运算还是算术运算,1是逻辑运算,0是算术运算
- S0-S3可以用来指明此次要进行的是哪一种算术运算或者哪一种逻辑运算
- 此处有4个bit,可以对应16种状态,因此该芯片可以支持16种算术运算和16种逻辑运算
- 机器字长的真面目就是ALU算术逻辑单元里面可以支持同时输入多少个比特的信息
- 寄存器的位数和ALU一般保持一致,也即一般寄存器的位数就是机器字长
- 其余输入和输出信号一般是为了和其他芯片进行串联而设计的
最基本的逻辑运算
- 一个比特的逻辑运算
- 关于数据的输入和输出,我们都是用电信号来表示的,也就是高低电平
- 与门
- 或门
因为只要有一个1结果就是1,即>=1
- 非门
- 优先级:与>或
复合逻辑
- 异或门可用与、或、非组合实现
- 异或的天然逻辑:加法、奇偶校验
- 同或门
用门电路求偶校验位
一位全加器
串行加法器
![](/img/ 113045.jpg)
并行加法器
- 串行进位的并行加法器
这种加法器的运算速度很大程度上取决于每一位进位的产生速度
2.2.2 并行进位加法器
更快产生进位
并行加法器的优化
2.2.3 补码加减运算器
加法器原理
补码加/减法运算方法
- 有符号整数和无符号整数的加减法虽然共用一套电路,但是判断是否溢出的方式不同
2.2.4.1 加减运算和溢出判断
原码的加减运算
补码的加减运算
- -B的补码是B的右数第一个1的左边所有位全部取反
溢出判断
核心逻辑:两个同号的数相加,最终得到了一个异号的结果
- 方法一:采用一位符号位
- 左边判断是否负+负得正,右边判断是否正+正得负,两个结果只要有一个溢出即答案得1,最后就是存在溢出现象,所以用或运算或起来
-
方法二:采用一位符号位,根据数据位进位情况判断溢出
- 上溢
- 下溢
- 只要发生了溢出,符号位的进位和最高数值位的进位肯定不一样
-
方法三:采用双符号位
补码在进行运算之前会复制一个符号位,接下来会让两个符号位同时进行运算
符号扩展
- 正整数:
- 符号位和数值位中间补0
- 负整数:
- 原码:符号位和数值位中间补0
- 反码:符号位和数值位中间补1
- 补码:符号位和数值位中间补1
- 正小数:
- 最后一位后面补0
- 负小数
- 原码:最后一位后面补0
- 反码:最后一位后面补1
- 补码:最后一位后面补0
2.2.4.2 标志位的生成
-
注:
- OF: overflow flag
- SF: sign flag
- ZF: zero flag
- CF: carry flag(进位、借位标志)
-
OF的标志位仅在有符号数的加减运算中有意义,即如果进行的是无符号数的加减运算,即便OF=1也并不能说明无符号数发生了溢出
-
如果减法的CF结果为1,说明产生了借位,也说明被减数比减数要小,意味着最终运算的结果一定是错误的,发生了溢出
-
有符号数的溢出看OF,无符号数的溢出看CF,都是1为溢出
2.2.5 定点数的移位运算
原码的算术移位
- 算数右移
- 算数左移
- 注:参考C++中的位运算,X>>k等于X/ 2^k,X<<k等于X* 2^k
反码的算术移位
补码的算术移位
算术移位的应用举例
逻辑移位
逻辑移位的应用举例
循环移位
- 循环补位,移出去的补到最后一位或者最前一位
- 带进位位的循环移位,相当于把进位位加入队列
- 循环移位很适合把数据的高字节和低字节进行一个调换
2.2.6.1 原码的乘法运算
手算乘法(十进制)
手算乘法(二进制)
原码一位乘法
原码一位乘法(手算模拟)
- 由于补码乘法用的是双符号位,所以原码的乘法也可以用双符号位以便统一
- 自己答题时最好还是写出真值所对应的源码机器数
2.2.6.2 补码的乘法运算
补码一位乘法
- 辅助位就是把MQ寄存器的容量多拓展了一位,用新拓展的一位来存储的
- MQ中的最低位指的是当前参与乘法运算的那一位
- 原码往ACC、X和MQ里面存绝对值,而补码是直接把符号位也一并存进去了
- 被乘数和乘积高位采用的是双符号位补码,而乘数、乘积地位采用的是单符号补码
补码一位乘法(手算模拟)
2.2.7.1 原码的除法运算
手算除法(十进制)
手算除法(二进制)
原码除法:恢复余数法
原码除法:恢复余数法(手算)
- 写出①除数和②被除数的绝对值,以及③除数的绝对值的补码和④绝对值负数的补码
原码除法:加减交替法(不恢复余数法)
- 在定点小数的除法运算中,我们会规定被除数一定要小于除数,因为如果大于,则商会>1,而定点小数无法表示大于1的范围,因此当第一步的商是1,说明被除数比除法更大,硬件电路检测出以后会直接停止这些除法的运算
2.2.7.2 补码的除法运算
补码除法:加减交替法
除法运算总结回顾
2.2.8 C语言类型转换
- 无符号数和有符号数
- 长整数变短整数
- 短整数变长整数
2.2.9 数据的存储和排列
大小端存储
- 大端存储就是把更高有效字节存储到更低地址的部分,最低有效字节存放到了最高地址部分
- 小端存储就是在低地址部分存储最低有效字节,在高地址部分存储最高有效字节
- 小端方式便于机器处理类似于高精度运算中数字用数组倒存
边界对齐
- 注:字节是基本单位,一字节等于8bit,字长是运算的基本单位,即以此能处理多少个字节,多少位就是多少个bit,处理的字节数等于bit/8,半字就是字长的一半
- 给出访问的字的地址的时候,如何转化为与之对应的字节地址:
- 字地址逻辑左移两位
- 半字地址逻辑左移一位
2.3 浮点数的表示与运算
2.3.1 浮点数的表示
- 定点数可以表示的数字范围有限,但我们不能无限制地增加数据的长度
从科学计数法理解浮点数
- 阶符为正,小数点右移,阶符为负,小数点左移
- 阶码的数值部分意味着要移多少位
- 尾数越短,表示的数字精度就越低
浮点数的表示
- 定点数之所以称为定点数是因为小数点的位置固定不变,而浮点数就是小数点的位置是会浮动的
- 阶码反应浮点数的表示范围及小数点的实际位置
- 尾数M的数值部分的位数n反应浮点数的精度
- 尾数给出了一个小数,阶码指明了小数点要向前/后移动几位
浮点数尾数的规格化
- 左规:通过算术左移来把浮点数进行规格化
规格化浮点数的特点
2.3.2 IEEE 754
移码回顾
IEEE 754标准
- 在实际计算的时候,可以先把移码看成是无符号数,转换成十进制再减掉偏移量
- 十六进制一位数字对应4个bit
2.3.3 浮点数的运算
浮点数的加减运算
- 通常是阶数更小的向阶数更大的对齐
舍入
强制类型转换
- 64位机器里面long向double转换可能产生精度丢失