内容基于中国大学MOOC的2023考研计算机组成原理课程所做的笔记。
感谢LY,他帮我做了一部分笔记。由于听的时间不一样,第四章前的内容看起来可能稍显啰嗦,后面会记得简略一些。
西电的计算机组织与体系结构课讲法和王道考研的课不太一样,要应付校内考试建议还是跟着老师学比较好。以下是20年西电计科院车向泉老师这门课的录播下载链接(请勿将录像上传到B站等网站!!):
链接:https://pan.baidu.com/s/1bFs3ajhy8ZcbHopS9izGsw
提取码:fdez
期中考试占20分,一般只考前两章内容,期末考试占60分,一般前两章内容不考,考察内容一般考前的复习课都会讲清楚,请务必认真听复习课。
其他各章节的链接如下:
数据的表示和运算
本章探讨数据如何在计算机中表示,运算器如何实现数据的算数、逻辑运算
进位计数制
十进制计数法
推广:r进制计数法
任意进制 —> 十进制
二进制 <—> 八进制、十六进制
各种进制的常见书写方式
十进制 —> 任意进制
十进制 —> 二进制(拼凑法)
真值和机器数
比如+15和-8是真值,01111和11000就是对应的机器数。后面学的反码/原码/补码/移码都是为了在计算机里表示带有正负的数
BCD码
BCD: Binary-Coded Decimal,用二进制编码的十进制
BCD码
无符号整数表示和运算
无符号整数在计算机中的应用
无符号整数的表示
如果一个计算机的机器字长是8位,这就意味着这个计算机同时只能处理8位的运算,也限制了计算机内部通用寄存器总共有多少位
放到计算机内部时要扩展为和机器字长相同的长度,高位需要全部补0
无符号整数的加法运算
无符号整数的减法运算
带符号整数表示和运算(原/反/补)
带符号整数在计算机中的应用
带符号整数的表示
原码表示
原码的缺点
原码 —> 反码 —> 补码的转换(机算)
双向箭头表示做法一样
把补码转变成反码,可以先把补码转变成原码。计算机把补码转换为原码和原码转补码一样,符号位不变数值位取反,再在末尾+1
原码、补码快速转换技巧(手算)
补码的加法运算
例1:
例2:
补码的减法运算
可以参考原码转补码的快速转换技巧求数的负值的补码表示
例3:
和无符号整数的减法运算中对减数的处理方法一样,可以用同一套电路实现无符号整数的减法以及有符号整数的减法
带符号整数移码表示
原、反、补、移码的转换
移码
原/反/补/移码特性对比
各种码的基本特性总结
用几种码表示整数
练习:
定点小数表示和运算
定点整数、定点小数
定点 —— 小数点的位置固定
定点整数和定点小数的区别在于默认的小数点隐含位置不一样
之前学习的带符号整数又可以称为定点整数,默认小数点固定在最后这个位置
计算机内部的定点小数默认小数点隐含在符号位的后面这个位置
如果要用定点的方式表示19.75这样的数就需要把整数部分和小数部分各自单独保存
原码
在书本里面定点整数符号位的后面通常用“ , , ,”隔开,定点小数符号位的后面通常用“ . . .”隔开
定点小数原/反/补码的转换
定点小数的加/减运算
定点小数 vs 定点整数
小数补码的加法运算
例1:
例2:
小数补码的减法运算
例3:
奇偶校验码
前几节讲了数字字符这些简单的数据应该怎么在计算机内部进行表示,这些数据在计算机内部进行计算存取传送的过程中由于计算机元器件可能发生故障或者某些环境噪音干扰导致我们在计算机内部存储传输的这些二进制数据发生错误。所以就必须考虑到数据校验问题
校验原理
奇偶校验码
算术逻辑单元 电路基本原理&加法器设计
经过之前的学习,我们已经知道了数据在计算机里如何表示,数据之间运算的基本数学原理。从这一小节开始会简单的介绍ALU的大致构成。在之前的讲解中可以体会到加法是实现很多计算的基础,无论是乘法还是除法,他们的实现都要借助加法来完成,所以如何用硬件来实现加法是个需要重点探讨的问题
首先简要回顾一下算术逻辑单元ALU的作用
算术逻辑单元( ALU )
上图下部左边是一个比较抽象的ALU图示,右边则是具象的。 A i A_i Ai和 B i B_i Bi表示输入信号,就比如我们想实现两个8bit二进制数的加法,这两个数就从 A i A_i Ai和 B i B_i Bi输入,我们输入的本质上是一些电信号也就是我们刚开始提到的高低电平。加法控制信号由控制单元CU发出
右边 S 0 ∼ S 3 , M S_0\sim S_3,M S0∼S3,M是来自CU的控制信号,控制单元会负责解析指令的含义(即一条指令是加法,减法,乘法,除法还是某种逻辑运算的指令),CU解析完指令后会根据指令的含义发出控制信号,每个信号就是1个高低电平。这里电信号M用来指明当前ALU要执行的是逻辑运算还是算术运算,M=1表示逻辑运算,M=0表示算术运算。 S 0 ∼ S 3 S_0\sim S_3 S0∼S3这几个信号可以用来指明这次要进行的是哪一种逻辑运算或哪一种算术运算。A和B就是两个4bit的数据,输入两个4bit的数据然后ALU经过加减乘除的运算之后会有一个4bit的输出。我们在这门课刚开始的时候提到过机器字长的概念,机器字长指的是计算机能同时处理多少个比特的整数运算,而机器字长的真面目其实就是ALU可以支持同时输入多少比特的信息。一般来说ALU能处理多少比特的数据,通常就会把这些寄存器的位数和ALU保持一致。因为这里ALU输入两个4bit的信息然后输出1个4bit的运算结果,这些4bit的运算结果肯定也得被放回到某个寄存器里面,为了让寄存器和ALU能完美适配,ALU多少位寄存器也会对应地被设计为多少位
这也是为什么我们在第一章说一般来说寄存器的位数就是机器字长
除了刚才这些部分之外左边还有一些输出,下面还有一个 C − 1 C_{-1} C−1。这些输入和输出信号是为了和其他的芯片进行串联而设计的,具体有什么作用不必深究。在这儿只需要体会到ALU需要有输入信号,输出信号和一些控制信号,这就是最基本的要求
最基本的逻辑运算
接下来我们会探究ALU到底是如何实现那些算术运算和逻辑运算的。无论再复杂的运算本质上都是通过我们之前提到过的这些基本逻辑运算来实现的,这儿所谓的逻辑运算指的是1个位1bit的运算
复合逻辑
到此为止我们介绍了各种各样的,这些门电路就是用来实现某些逻辑运算的,门电路的输入和输出信号本质上就是一些高低电平。通过这些门电路的组合我们就能实现更复杂的逻辑,比如“加法”和“奇偶校验”。下面来看一下怎么实现
再来复习一下奇偶校验码,偶校验就是要保证当我们在加入校验位之后整体来看1的数量总共有偶数个。之前我们说过偶校验的这种逻辑和异或有天然的对应,因为我们对偶数个1进行异或的话最终结果是0,刚好可以对应偶校验想求得的这个校验位,如果为我们对奇数个1进行异或的话最终结果是1,同样也可以对应到偶校验位所需要的校验位。之前我们是站在数学的角度探讨,接下来看如何用电路来实现
之前我们是站在数学的角度探讨,接下来看如何用门电路求偶校验位。有多种实现方式。逻辑表达式是对电路的数学化描述,只要我们写好了逻辑表达式本质上就已经设计好了电路,因为所有的这些逻辑运算符和门电路都是一一对应的
接下来看如何用异或门实现加法运算
一位全加器
首先从我们熟悉的手算加法出发,这下边的一排小字指的是每一位对高位的进位。为了方便描述我们给这些相对应的比特位取一些名字。 A , B A,B A,B是两个相加的二进制数, A i , B i A_i,B_i Ai,Bi指的是这两个数中的第 i i i位,当前我们正在运算的这一位称为本位, C i − 1 C_{i-1} Ci−1表示来自低位的进位, S i S_i Si表示本位的和。两个本位的数还有来自低位的进位进行相加之后会得到本位的和并且还会对高位有一个进位
通过这个例子能感受到我们在进行加法的时候是一位一位地加的,先进行低位的加法,两个本位和一个来自低位的进位可以确定我们这一位的本位和是多少以及应该向高位进一个什么数值。所以当我们在设计加法电路的时候需要输入的就是本位的两个比特信息和一个来自低位的进位数值,通过这些信息得到输出
第一个输出要确定本位和 S i S_i Si是多少,我们的输入信号有3个,如果这3个数当中有奇数个1时 S i = 1 S_i=1 Si=1。之前我们说过判断奇数个1还是偶数个1的逻辑天然的可以用异或门来实现,所以本位和只需要让这3个输入信息进行异或就可以,当这3个信息当中有奇数个1的时候相异或的结果就应该是1
另外一个需要确定的是我们应该向高位进什么位,进0还是进1。有两种情况可能产生进位,第一种是A和B它们所对应的这一位都是1,在这种情况下不管来自低位的进位到底是0是1一定都是要向高位进1个1的。另一种可能发生进位的情况是A和B当中本来就有1个1,并且来自低位的进位也是1
根据 S i S_i Si和 C i C_i Ci的逻辑表达式就能得到与之相对应的电路。下图下部右边就是把下图下部左边简化一下,屏蔽其内部的电路细节得到的形式。通过这个硬件电路我们就能实现一位的加法
接下来我们来看如何用刚才设计的一位全加器来实现多位的加法。第一种实现方式叫串行加法器
串行加法器
顾名思义所谓串行就是一位一位的加。实现方式是加一个进位触发器以保存进位位是0还是1,用这样的方式一位位的进行加。这种串行加法器的效率是比较低的
结合上图应该不难理解其工作原理,此处具体讲解就略过不记了
串行进位的并行加法器
与串行相对应的是并行这个概念。把多个全加器串联起来,这样就能同时输入两个n位的数。显然虽然刚开始我们就可以同时输入A和B这两个数各个数值位的信息,电路实际的运算速度很快,然而这些电信号的传递依然是需要时间的。也就是只有更低位的运算执行结束之后我们才能确定应该往高位进一个什么样的信号,而如果往高位进的信号发生改变,那么高位的和和这一位往更高位的进位也会发生改变。所以这种并行加法器被称为串行进位的并行加法器,这些进位信息我们都是串行着一位一位往前进的。只有来自低位的信号确定了,我们才能确定本位的和还有往更高位的进位,因此这种加法器的运算速度很大程度上取决于我们每一位进位的产生速度,这个问题如何优化在下一小节会探讨
同样结合上图应该不难理解其工作原理,一些讲解就略过不记了
并行进位加法器
如何产生更快的进位?
并行加法器的优化
通过 A A A和 B B B对应的两个比特位可以算出与之对应的 G i G_i Gi和 P i P_i Pi, G i G_i Gi和 P i P_i Pi的信息可以通过线路送往更高位的运算当中,更高位的这些运算的进位的确定依赖 G i G_i Gi和 P i P_i Pi
计算 C i C_i Ci进位的信息,在刚开始就已经把所有的计算所需要的数据准备好了,只需要根据表达式设计相应的电路就可以在第 i i i个全加器那直接算出 C i C_i Ci的值。采用这种策略每一位的进位几乎都是同时产生的
为了防止逻辑表达式过长过复杂,电路设计过于复杂,套娃的过程应该适可而止。比较经典的做法是套到 C 4 C_4 C4这一位
补码加减运算器
加法器原理
计算机底层硬件在处理加法或者减法时不会管给它的数是有符号数还是无符号数,都按同一套硬件来处理,但是最后判断是否发生溢出时有符号数和无符号数通过不同的标志位判断溢出
标志位生成
移位运算
算数移位
移位:通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权。可用移位运算实现乘法、除法
上图是大家熟悉的十进制,对于之前小节中学习的二进制也是一样的。对于定点数来说没办法改变小数点的位置,但是如果可以移动数值部分,只要能改变每个数值位和小数点的相对位置关系同样可以实现算术移位运算
原码的算数移位
原码的算数移位符号位保持不变,仅对数值位进行移位
右移:高位补0,低位舍弃。若舍弃的位 = 0 =0 =0,则相当于 ÷ 2 \div2 ÷2;若舍弃的位 ≠ 0 \neq0 =0,则会丢失精度
左移:低位补0,高位舍弃。若舍弃的位 = 0 =0 =0,则相当于 × 2 \times2 ×2;若舍弃的位 ≠ 0 \neq0 =0,则会出现严重误差
反码的算数移位
补码的算数移位
总结一下:
算数移位的应用举例
硬件在执行乘以7操作时相当于分别将-20不移位,左移2位,左移1位,再把得到的3个数相加。所以计算机硬件实现乘法其实是基于算术移位还有加法来进行的。而实现算术移位的硬件电路设计起来并不复杂。具体乘法怎么实现在之后的小节再讲
逻辑移位
逻辑移位的应用举例
在计算机里表示一种颜色时经常会使用RGB表示方式。自然界里所有的颜色都是由红绿蓝这三种三原色按照一定配比组成的。比如对于某种颜色R G B值分别为102 139 139
有时我们存储一个像素点的R G B值时需要把R G B这三个值连成3个字节的一个整体,第一个字节存放R,第二个字节存放G,第三个字节存放B。怎么将其拼成3个字节的整体呢?见下图:
循环移位
什么叫进位位CF?
进位的概念之前说过,比如现在对两个8位二进制数10011001和10000000进行加法操作,当运算到最高位时往高位进1得到100011001。由于机器字长有限寄存器只能保存8个二进制位,而最高位又确实产生了1进位,为了实现超过8 b i t bit bit的数据加法,计算机硬件里会包含所谓的进位位来记录下低位的运算有没有产生进位。把这个进位保留下来,之后在进行更高字节的运算时就可以得到正确的结果
循环移位不考虑进位位时,用移出的位补上空缺
考虑进位位时,移出的位放到进位位,原进位位补上空缺
循环移位操作很适合用于把一个数据的高字节和低字节进行调换。比如“啊”这个汉字需要占两个字节的位置,有大端存储和小端存储两种方式,大端存储就是先存放高字节再存放低字节,而小端存储是先存放低字节再存放高字节。如果要在大端存储和小端存储之间实现相互转化,直接循环移位就很方便,循环右移8位或者循环左移8位就可以实现高低字节的调换