本系列文章为408考研计算机组成原理知识点整理仅涉及到一些重要的考研知识点并不是完全系统全面的知识,参考书目和视频资料:唐朔飞 计算机组成原理(第二版),袁春风 计算机组成与系统结构(第二版)王道考研计算机组成原理,B站王道考研计算机组成原理视频课。
2.1 数制与编码
学习基础:熟练掌握各种进制的表示和转换
2.1.1 BCD码
BCD码(Binary-Coded Decima):是指二进制编码的十进制数。我们可以用4位二进制数来表示一位十进制数中的0~9,这种编码方法使得二进制数和十进制数之间的转换得以快速进行。4位二进制数最多有16种组合,足以表示0到9这十个数,所以有6种状态为冗余状态。
常用BCD码
8421码
8421码(Binary-Coded Decimal):它是一种有权码,设其每一位的数值为b1,b2,b3,b4,则权值从高到低依次为8,4,2,1。
8421码运算规则:
如果两个8421码相加之和小于等于(1001)2不需要修正:
如果两个8421码相加之和大于(1001)2则需要修正:修正时需要+6
余3码
余3码是一种无权码,是在8421码的基础上加(3)10,也即(0011)2形成的。
2421码
2421码是一种有权码。权值由高到低分别为2421,特点是大于等于5的4位二进制数中最高位为1,小于5的最高位为0。
2.1.2 无符号数的表示与运算
无符号整数(无符号数):无符号整数是指整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值,它就是我们常说的自然数;n位无符号数其范围为(0,2n一1)。
无符号数加法运算
无符号整数加法运算规则:从低位开始,按位相加,向更高位进位
无符号数减法运算
无符号整数减法运算规则:由于减法电路实现较加法电路困难,所以成本较高,因此会将减法运算转换为加法运算来完成运算。具体来说:
被减数不变,减数按位取反、末位+1;从低位开始,按位相加,向更高位进位
2.1.3 有符号数的表示与运算
有符号数:由于计算机是无法直接识别数的正负的,所以可以将符号数值化。规定:对于有符号数用"0"表示正,用"1"表示负,且通常约定二进制数位的最高位为符号位。有符号数分为定点整数和定点小数。定点整数和定点小数可以原码、反码、补码和移码来表示。
原码
原码:原码是一种比较简单、直观的机器数表示法。用机器数的最高位表示该数的符号,其余的各位表示数的绝对值,其中0表示正,1表示负。
- 原码整数的表示范围:假如机器字长为n位,那么原码整数的表示范围为 :-(2n-1-1)≤x≤2n-1-1
- 原码小数的表示范围:假如机器字长为位,那么原码小数数的表示范围为:-(1-2-n+1)≤x≤1-2-n+1
- 原码真值0有+0和-0两种形式
反码
反码:反码是原码转换为补码的一个中间状态
- ①:如果是正数,则反码与原码相同
- ②:如果是负数,则除符号位外,其他位按位取反
真值0的+0和-0对应的两种不同的形式
补码
- ①:如果是正数,则补码和原码一致
- ②:如果是负数,则补码=反码+1(注意进位)
- ③:特别注意的是补码的真值0只有一种表现形式
因为[-0]原=10000000,[-0]反=11111111,其补码如果在此基础再加1,就会超出机器数位的限制(这里假定8位),变为1,00000000。这样一来,低八位就又变成了00000000,反而和+0冲突了,并目显得浪费,所以把我们这个特殊的补码直接规定为-128。所以这里如果机器字长为n位,那么补码整数的表示范围就为(多了一个128):-(2n-1)≤x≤2n-1-1
相应的,补码小数1.00000000的表示范围会变为(多了一个1):-1≤x≤1-2-n+1
Tips:如果已经知道X的补码,让我们求-X的补码,只需所有位全部取反,末位+1即可
移码
移码:移码是在补码的基础上将符号位取反,需要注意移码只能用于表示整数,且移码和补码的真值0只有一种表示形式。
移码是补码的符号位取反,可以将其看做一个无符号数,因此直值增大时移码也在增大。
有符号数的补码运算
定点整数加法运算
定点整数补码加法运算规侧:从最低位开始,按位相加(符号位参与运算),向更高位进位
定点整数减法运算
定点整数补码减法运算规测:[A]补-[B]补=[A]补+[-B]补,所以问题就在于已知[B]补如何求[-B]补,回忆一下上面的Tips:如果已经知道X的补码,让我们求-X的补码,只需所有位全部取反,末位+1即可。所以减法运算这样就成为了加法运算。
定点小数的加法和减法运算分别和整数的加法减法运算规则相同
2.1.4 溢出判断方法
溢出分为上溢出和下溢出。
正数+正数导致上溢:正+正=负
负数+负数导致下溢:负+负=正
采用一位符号位依据溢出表达式判断
假设A的符号位为As,B的符号位为Bs,其运算结果符号位为Ss。,则溢出逻辑表达式为V
V=O表示无溢出,V=1表示有溢出
采用一位符号位依据进位情况判断
这里有两个进位:
符号位的进位Cs:最高数值位向符号位进的位
最高数值位的进位C1:最高数值位得到的进位
溢出判断规则为:上溢:Cs=0,C1=1 ; 下溢:Cs=1,C1=0.可以发现只要发生溢出Cs,和C1一定是不同的,计算机在判断时会使用异或运算。相同时为0表示无溢出,不同为1表示有溢出
采用双符号位判断
之前符号位都是一位,这种方法将符号位扩展为了2位:用“00”表示正数,“11表示负数”。
运算结果符号位自然也有两位,这两个符号位第一位表示本来应该的符号,第二位符号表示运算实际得到的符号。在判断时依然使用异或运算。相同时为0表示无溢出,不同为1表示有溢出。
2.1.5 符号扩展
对于定点正整数来说,由于其原码、反码和补码都一样,因此直接补0即可
对于定点负整数来说,原码补0,反码和补码则对应位置补1
2.2 定点数的表示与运算
2.2.1 基础电路知识和加法器
与、或、非
与:只有A和B全部输入为高电平时,Y才会是高电平,只要有一个是低电平Y就会是低电平
或:如果A和B输入中有一个是高电平时,Y就会是高电平,只有全部输入为低电平时,输出才会是低电平
非:输入的是高输出的就是低,反之亦然
与非、或非、异或、同或
与非:实则是与运算取反:也就是说全1则为0,全0则为1,有1则是1
或非:实则是或运算取反;也就是说全1则为0,全0则为1,有0则是0
异或:相同数异或运算结果为0, 0异或任何数是任何数
同或:相同数同或运算结果为1, 1同或任何数是任何数
一位全加器
一位全加器:一位全加器(FA)是最基本的加法单元,首先注意以下两个概念:
- 本位:指的是当前运算的那一位
- 本位的和:包括本位对应的两个数和来自低位向本位的进位
运算时是按照一位一位的方式加的,来自本位的两个数和来自低位的进位会确定本位的和,同时确定向高位进位的数值
串行加法器
串行加法器:串行加法器中只有一个全加器,数据会逐位串行送入加法器中进行运算。进位触发器用来寄存进位信号,以便参与下一次运算
缺点:如果操作数为n位,加法就要分n次进行,每次产生一位和并且串行逐位送回寄存器中,所以效率非常低。
并行加法器
串行进位
串行进位的并行加法器:最简单的并行加法器是串行进位的并行加法器:是将多个全加器串联在一起,这样就能同时输入两个位的数,每一位都可以使用一个加法器进行运算,且低位加法器产生的进位,会作为下一个高位加法器的输入信号。
缺点:电信号的传递时需要时间的,因此高位的操作会受到低位的限制。
并行进位
并行加法器(并行进位):与串行进位的并行加法器相比,并行进位的并行加法器的各级进位信号同时生成,即同时进位,大大提高了效率。
2.2.2 补码加减法运算器和标志位
补码加减法运算器
如下图是补码加减运算器,其中红色线上方和普通的加法器是一样的,下方是为实现补码运算所增加的电路。在进行补码运算时,对加减运算的区分会由信号sub给出(输入0做加法,输入1做减法),该信号会传送给一个多路选择器MUX,让其接通加法或减法电路。
在实现加法功能时,输入Sub为0,多路选择器直接连接Y的一端会被选通,Cin为0,然后进行运算即可。
实现减法功能时,输入Sub为1,Y会进入带有非门的一端,经过非门后Y会被取反,然后让Cin为1,相当于取反后再+1,接着完成运算即可。
标志位的生成
- OF(溢出标志):溢出为1,否则为0(仅对有符号数加减法有意义)
- SF(符号标志):结果是负为1,否则为0。(仅对有符号数加减法有意义)
- ZF(零标志):运算结果是0位1,否则为0
- CF(进位借位标志):需要进位/借位时为1,否则为0 (仅对无符号数加减法有意义)
硬件产生判断
OF硬件产生方法:最高位产生的进位Cs⊕次高位产生的进位C1。相同结果为0表示无溢出,不同结果为1表示有溢出。注意OF仅对有符号数加减法有意义
SF硬件产生方法:它等于最高位的本位和,注意SF仅对有符号数加减法有意义
ZF硬件产生方法:只有当运算结果所有比特位全为0时,ZF才等于1
CF硬件产生方法:最高位产生的进位Cs⊕Sub信号,注意CF仅对无符号数加减法有意义
2.2.3 定点数移位运算
算数移位
算数移位的对象是有符号数,在移位的过程中符号位保持不变。
逻辑移位
逻辑移位比较简单,可以看作是对“无符号数”的算数移位
逻辑右移时高位补0,低位舍弃
逻辑左移时低位补0,高位舍弃
循环移位
循环移位分为如下两种:
- 带进位标志位CF的循环移位(大循环)
- 不带进位标志位的循环移位(小循环)
循环移位的特点:算术移位和逻辑移位中不管是左移还是右移,原始数值位都会有二进制数被移出丢弃。但循环移位的二进制数在移位过程中不丢弃,这也使循环移位操作特别适合将数据的低字节数据和高字节数据互换。
2.2.4 定点数乘法运算
原码一位乘法
设[X]原=Xs,[Y]原=Ys
1.被乖数和乘数均取绝对值参与运算,符号位为Xs⊕Ys
2.部分积的长度同被数,取n+1位,以便存放乘法过程中绝对值大于等于的值,初值为0
3.从乘数的最低位yn开始判断:若yn=1,则部分积加上被乘数|x|,然后右移一位;若yn=0,则部分积加上0,然后右移一位。
4.重复步骤3,判断n次
由于乘积的数值部分是两数绝对值相乘的结果,因此原码一位乘法运算过程中的右移均为逻辑右移
考虑到运算时可能出现绝对值大于1的情况(但并非益出),所以部分积和被乘数取双符号
补码一位乘法(Booth算法)
①:被乘数与部分积一般取双符号位,并且符号位参与运算。
一个原因是一旦符号位参与运算就一定要使用多符号位,因为一旦溢出,单符号位就会出错
另一个原因是,补码的右移时要看符号位而定的,如果采用单符号位,一旦数值部分的进位把符号给移掉了,下次移位就不知道该怎么办了。
②:乘数取单符号位以决定最后一步是否需要校正,也即是否需要加[-x]补
③:乘数末尾增设辅助位,yn+1,初始值为0
④:根据yn,yn+1判断位,进行运算,步骤和上面原码一位乘法一致
⑤:按上述算法进行n+1次(n+1次累加),其中最后一步也即n+1步不再移位(右移n次),仅根据y0,y1比较结果决定是否需要加减[X]补
2.2.5 定点数除法运算
原码一位除法:恢复余数法
关键点:
符号位异或运算得出
逻辑左移
若最后一步商余数为负,也需要恢复余数并商0
原码一位除法:不恢复余数法
关键点:
若余数为负,直接商0,并让余数左移1位再加上除数,得到新余数
若余数为正,直接商1,并让余数左移1位再减去除数,得到新余数
所以这个方法又称加减交替法,但要注意:最后一步如果出现负数,仍然需要恢复余数
补码一位除法
补码除法采用加减交替法完成,与原码除法的有所区别的是:
符号位参与运算
被除数(余数)、除数采用双符号位
运算的具体细节区别如下
原码除法中,首先一上来就会让被除数减去除数的绝对值的补码;在补码除法中,若被除数和除数同号,则被除数减去除数,如果异号,则被除数加上除数。
得到新的余数后判断:若余数和除数同号,则商1,余数左移一位减去除数;若余数和除数异号,则商0,余数左移一位加上除数。
在原码除法中如果最后一步余数出现负值,那么需要进行恢复余数;在补码除法中,我们直接把最后一位商置为1即可,这样做很省事,其精度也不会超过2-n
下表是对除法加减交替法的一个小结(重点掌握这个表的内容)
2.3 C语言强制类型转换
2.3.1 强制类型转换
无符号数与有符号数进行强制类型转换:把一个有符号转换为了无符号,并用无符号变量保存;在这个过程中数据的内容是没有被改变的,只是改变了解释的方式。
长整数变为短整数:具体规则为:高位截断,保留低位
短整数变为长整数:具体参考之前2.1.5符号扩展那一节。
2.3.2 数据的存储和排列
大小端存储
在存储数据的时候,数据从低位到高位可以从左到右排列,也可以按从右到左的方式排列。因此,我们无法用最左或最右来表征数据的最高位或最低位,通常用最低有效字节(LSB)和最高有效字节(MSB)来分别表示数的低位和高位。
多字节数据都存放在连续的字节序列当中,根据数据中各字节在连续字节序列中的排列顺序不同,可以有两种方式:大端方式(先存高位)和小端方式(先存低位)
下面是对01 23 45 67H按大小端方式存储的例子:
边界对齐
假设存储字长为32位,可按照字节、半字节和字寻址。对于机器字长为32位的计算机,数据以边界对齐方式存储,半字地址一定是2的整数倍,子地址一定是4的整数倍,这样无论所取的数据是字节、半字还是字,均可以一次取出,当存储的数据不满足上述要求时,通常填充空白字节使其符合要求,典型的以空间换时间的做法。
有两点说明:(1)存放某长度为m字节的数据存放首地址应该为m字节的整数倍
(2)结构体整体的大小应该是最大成员长度的整数倍
2.4 浮点数的表示与运算
2.4.1 浮点数的表示
左规和右规
为了提高运算的精度,需要充分利用尾数的有效数位,通常采取浮点数规格化形式,即规定尾数的最高数位必须是一个有效值。非规格化浮点数需要进行规格化操作才能变成规格化浮点数。所谓规格化操作,是指通过调整一个非规划浮点数的尾数和阶码的大小,使非零的浮点数在尾数的最高位上保证是一个有效值。
左规:将尾数算数左移一位,阶码就减1(基数为2),左规可能要进行多次
右规:当浮点数运算的结果尾数出现溢出(双符号位为01或10)时,将尾数算数右移一位,阶码加1(基数为2时)的方法称为右规,右规只需进行一次。
下面是一个例子:
规格化浮点数的特点
规格化浮点数的尾数M的绝对值应该满足,1/r≤|M≤1,若r为2,则有;1/2≤M|≤1。规格化表示的尾数形式如下:
原码规格化后
规格化的原码尾数,最高数值位一定是1
正数:形式为0.1×..×,其最大值表示为0.111..1,最小值表示为0.100..0,尾数的表示范围为1/2≤M≤(1-2-n)
负数:形式为1.1×..×,其最大值表示为1.10××0,最小值表示为1.111..1,尾数的表示范围为-1/2≥M≥-(1-2-n)
补码规格化后
规格化的补码尾数,符号位与最高数值位一定相反
正数:形式为0.1×..×,其最大值表示为0.111..1,最小值表示为0.100..0,尾数的表示范围为号1/2≤M≤(1-2-n)
负数:形式为1.0×..×,其最大值表示为1.01×x1,最小值表示为1.00..0,尾数的表示范围为-1≤M≤-(1/2+2-n)
举例:若某浮点数的阶码,尾数用补码表示,共4+8位:0.110;1.1110100,问如何规格化?
答:在这个例子中,阶数为+6,前面说过我们规定规格化的补码尾数的负数形式一定为1.0××..×,因此可以将1.1110100算数左移三位(补码的算数左移是低位补0,算数右移是高位补1),结果为1.010000,阶码变为+3。
2.4.2 IEEE754标准
IEEE754标准将浮点数分为短浮点数、长浮点数和临时浮点数三类,C语言遵循这个标准,因此它们分别对应float、double和long double。
数符:表示了整个浮点数的正负性
阶码:采用移码表示,并且短浮点数的偏置值为127。所以原本8位的移码表示的真值范围为-128~127,但是127的偏置值会使真值-127和-128较为特殊,其移码是全0和全1,全0和全1在该标准下具有特殊解释,所以实际上8位的阶码表示真值的范围应该是-126到127
尾数:采用原码表示。并且我们知道使用原码表示浮点需要进行规格化,也就是最高位格式应该是1.M,所以短浮点数这里尾数部分写的虽然是23位,但是实则是24位。
我们知道移码=真值阶码+偏置值,那么自然而然阶码真值=移码-偏置值
因此IEEE754标准中,规格化的短浮点数和长浮点数的真值分别为:
表示范围
下面是几种特殊情况:
- 当阶码全为0,尾数不全为0时,表示非规格化小数,也即(+/-)(0.××××)2×2-126,阶码的隐含最高位为0
- 当阶码全为0,尾数全为0时,表示真值正负0
- 当阶码全为1,尾数全为0时,表示正负无穷大
- 当阶码全为1,尾数不全为0时,表示非数值NaN(Not a Number)
2.4.3 浮点数加减运算
1.对阶
所谓对阶就是对齐两个浮点数的阶数,由于计算机内部尾数是定点小数,所以对阶是一律向大阶看齐。
2.尾数加减运算
将对阶后的尾数按定点数加(减)运算规则运算。运算后的尾数不一定是规格化的,因此,浮点数的加减运算需要进一步进行规格化处理。
3.规格化
如果尾数加减出现了0.00xxxxx ×1012,就需要左规;如果尾数加减出现了11.xxxxxx ×1012时,需要右规
4.舍入
5.判断溢出
2.4.4 浮点数强制类型转换
在C程序中等式的赋值和判断常会强制类型转换,以下两种最为常见,其从前到后范围和精度都从小到大,转换过程没有损失
char->int->long->double
float->double
- 从int转换为float时,虽然不会发生溢出,但是int可以保留32位,float保留24位,可能有数据舍入;若int转换为double则不会出现这种情况。
- 从int或float转化为double时,由于double有效位数更多,因比能够保留精度
- 从double转换float时,由于float表示的范围更小,因此可能发生溢出。此外,由于有效位数变少,因此可能被舍入。
- 从f1oat或double转换为int时,由于int没有小数部分,所以数据可能会向0方向被截断(仅保留整数部分),可能有数据舍入,影响精度,同时由于int的表示范围更小,因此可能发生溢出。
Comments NOTHING