思维导图
数据的表示和运算
1.无符号整数的表示和运算
无符号整数的表示
无符号数的扩展开:高位补0
无符号整数的加减运算
2.有符号整数的表示和运算
有符号整数为什么要用补码运算
- 要计算A+B的值,机器就要先计算A+B的补码,计算的结果也就是A+B的结果的补码,真实的结果就是把这个补码再转化为真值(原码)
- 机器进行运算主要分为两步:先求补,再作加法
有符号整数补码的加法
有符号整数补码的减法
3.定点小数补码的加减运算【同有符号整数补码】
原反补移的总结
各种码的转换
各种码的基本特性总结
补充:
>int 、short…这些是有符号数
解读:机器数0000 0000 为什么对应移码是-128:
如果机器数表示的是移码,那么它对应的真值时-128
0000 0000【移码】—>1000 0000【补码】—>-128【真值】
定点数的移位运算
算数移位,符号位不变,左移= = >乘2; 右移== >除2
整数在机器中都是以补码的形式存在
看到算数移位,最高位那一位是不参与运算的
循环移位适合于把一个数据的高字节部分与低字节部分调换
进位位:当我们要用8bit字长的运算器计算两个16bit数据的运算时,会先对两个数据的低8位进行运算,
两个8bit的数据进行运算时,如果最高位产生了进位1,为了实现超过8bit的数据的一个加法,计算机硬件里面会包含一个进位的位来记录这两个8bit的数运算有没有产生进位,把这个进位保存下来
然后再对两个数的高8位进行运算,这时要同时带上进位位CF所保存的数据一同计算。这样就可以实现最终的运算
定点整数的符号扩展
对于一个负数:
对原码,从右往左找到第一个1,画一条竖线,1往后的数反码和补码相同,1和1右边的数,原码和补码相同
C语言类型转换【C语言中的数据在内存中为补码表示形式】
- 有符号数==>无符号数
C语言中描述的X=-4321,是这个数据的真值,但是这个真值在计算机中用补码的形式保存,所以转换时,先写出这个是数据的原码,再转换为补码。
把这个补码看成一串普通的二进制数。然后用无符号数的解释方式进行解释
C语言中描述的-32767是这个数据的真值,而计算机保存的是这个数据的补码
所以在进行转换时,先把这个数据的二进制原码写出来,然后再转换为补码,这个补码用无符号数的形式来进行解释!
- 长整数===>短整数
还是先写出这个输的原码,再转换为补码,再进行高位截断,对地位的数据用有符号short的解释形式进行解释。这儿由于计算机保存的是补码的形式,所以低位的这串二进制数也表示的是有符号数的补码,还需要先把这串二进制转为原码,再计算真值。
- 短整数==>长整数
先写出短整数的二进制,再转换为补码,然后对这个补码进行符号扩展,对扩展后的数据进行解释。注意:扩展后的数据仍然是补码,要求真值,先要转换为原码
移码
移码通常用于浮点数的阶码当中
电路基本原理&加法器设计
1.算数逻辑单元【ALU】
CU【控制单元】会负责解析指令的含义,比如说一条指令是加法、减法、乘法、除法或者是某种逻辑运算的指令。CU解析完这条指令之后,会根据指令的含义发出一些控制信号,就是一些0101的电信号【也就是图中S0-S3,他这些电信号用于指明要执行性哪一种运算(加减乘除等等)】
M:用于指明当前执行的指令是逻辑运算还是算数运算。M=1表示逻辑运算,M=0表示算数运算
CU给ALU发出一个控制信号OP,告诉ALU,你要执行什么运算(加减乘除)
ALU有两个输入,一个输出。还可能有标志位的生成
一般控制信号用虚线表示
2.最基本的逻辑单元
异或:只有A=0 B=1或者A=1 B=0的时候输出的结果为1
3.加法器的原理
注意:Cin要加到a和b的最低位
Cout是A和B相加之后,向更高位产生的一个进位信息
4.加法器的实现
一位加法器
串行加法器
串行进位的并行加法器
并行加法器的优化
如果要实现8位的计算,可以将两个4位的加法器串起来,这样第一个加法器的最高位的进位就变成了第二个加法器最低位的进位了。这就实现了加法的一个位扩展了
数据运算的底层实现
无符号整数的加减运算【与补码加减的电路结构相同】
有符号整数补码的加减运算底层实现
由于此时实现的是减法,所以sub的这根线也会控制Cin使Cin的值为1
问题!
无符号整数and有符号整数补码在进行加减运算时,相同二进制数运算,得到的结果不同,甚至有时候会溢出。
这是因为他们的溢出判断规则是不同的
那ALU又是如何知道自己采用哪种判断规则的呢?
ALU是无法区分是有符号加法还是无符号加法。但是我们可以通过使用不同的指令来区别
无符号加法和有符号加法区分:用不同的指令add和addu
两条指令各不相同,意味着这两条指令执行的时候,微操作是不一样的。两种数的加法操作大致是一样的,只是有一点微小的区别,无符号数加法中在检查溢出时看的是CF这一位。有符号加法中看的是OF这一位
如果产生了溢出,一般情况并不会发生内中断,不需要处理溢出
但是是如果是导弹的CPU那就需要处理溢出
标志位的生成
无符号数减法中,如果是小的减去大的,那他的结果应该是一个负数
无符号数没有负数,所以一定会产生借位
OF这个标志位只在有符号数的加减运算中才有意义
OF的例子
SF的确定:SF=最高位的本位和
对无符号数没有意义,因为无符号数没有正负之说
ZF对有符号and无符号都有意义
CF只对无符号数的加减法有意义
CF=Cout异或Sub,当然其实也是Cout异或Cin
乘除法运算
无符号乘法电路基本结构(前n比特全为0时不溢出)
- 控制逻辑检查到最后一位是1,那么接下来前面绿色的部分需要加上被乘数1101
- 起始,绿色部分为0000,然后进行一次加法之后,
- 控制逻辑发出一个写使能的信息,将结果写入到绿色部分
- 1101+0000往最高位的进位应该是0,也就是C=0
- 完成一次加法之后,所有的比特全部右移一位,刚才的进位信息C的值会移到最高位,同时舍去最低位。(右移是为了实现错位相加)
- 此时计数器应该减1(计数器的初值=被乘数or乘数的位数)
如果两个无符号数相乘,产生了溢出,就会使得PSW的OF位变为1,表示他是溢出。
但是这个OF位的产生方式就不再是用加法器实现了,可能是用一种乘法器,检查前n个比特是否全部为0,是的话,OF=0,不是的话,OF=1
有符号数的乘法(前n+1位全0or全1时不溢出)
- 不需要记录加法产生的进位,也就是说不需要C这个寄存器,因为有符号数中最高位通常是符号位,不会把他看做是进位
- 需要增加一个辅助位,设置为0
- 辅助位刚开始设置为0,Cn的值为4
- 每一轮的处理都要看辅助位和乘数Y的最末一位
- 0-1=-1,所以用P-X也就是P+(-X)的补码
- 0000-1101,减法他在底层是用加法实现的,也就是0000+0011=0011
- 把加得的结果写入P
- 把所有位算术右移,空出来的位置用原来的符号位(也就是P的最高位)填充
- 之后,计数器Cn的值减1,变为3
注意:-3*7=-21这个结果是正确的,但是只用了4位来保存乘积,所以说这个乘法是发生了溢出的(因为结果只能是:-8到7 )
当然也可以用后n+1位判断:因为后n+1位,也就是后5位:11101不是全1or全0,所以溢出
判断溢出(用10进制算更加方便)
无符号数乘法中:当且仅当前n为都是0时,不溢出
有符号数补码乘法中:前n+1位全0or全1则不溢出
为什么有符号数补码乘法中,前n+1位全0or全1时不溢出?
因为有符号数补码在进行符号扩展时,将n比特扩展为2n比特的话,原先的n比特数据中,最高的一位是符号位,补码在扩展后,前n+1位要么全0,要么全1
补码一位乘
- 补码一位乘中,我们使用了双符号的运算方式,所以在n轮的加法和移位之后,确实还需要多一次加法
- 上面的乘法使用的是单符号位的补码进行运算
除法电路的基本结构