因为学校的课程设置是没有计组,计网和操作系统。但是总觉得这些很重要,一些底层基础东西还是有必要去掌握。所以自此打算花费一到两个月来自学计算机组成原理。可能学习的不是很深入,毕竟不是学校系统的学习,但是了解一点基础也是极好的。此博客只记载自己所学习到的新东西,欢迎大家指正错误。2020.1.27
本博客的主要内容有:定点数和浮点数、反码、补码、移码及加减乘除的运算、强制转换等
目录
定点数
定点数和浮点数的区别
定点数:小数点的位置固定———常规计数:9960
浮点数:小数点的位置不固定———科学计数法:
定点数的表示
无符号数:相当于数的绝对值,没有符号位
表示范围:
n位的无符号数表示范围位:0~
有符号的定点表示
0为正,1为负
原码:用尾数表示真值的绝对值,符号位“0/1”对应“正/负”
原码整数的表示范围:
真值0有+0,-0两种形式
原码小数的表示范围:
反码
若符号位为0,则反码与原码相同
若符号位为1,则数值位全部取反
反码整数的表示范围:
真值0有00000000,11111111两种形式
原码小数的表示范围:
反码只是原码转变为补码的一个中间状态,实际并并没有什么用
补码
正数的补码=原码
负数的补码=反码末位+1
补码的真值0只有一种表示形式
定点整数补码
表示
若机器字长n+1位,补码整数的表示范围:
(比原码和反码多一个
)
定点小数的补码
表示x=-1
若机器字长n+1位,补码小数的表示范围:
(比原码和反码多一个
)
将负数补码转回原码的方法相同:尾数取反,末位+1
移码
补码的基础上将符号位取反。注意:移码只能用于表示整数
移码的真值0只有一种表示形式:10000000
若机器字长n+1位,移码整数的表示范围:
- 移码表示的整数很方便对比大小,谁先出现1,谁更大
原码补码移码的作用
一对补数的绝对值之和=模
计算机就相当于模是
,补码的作用就是可以让减法运算变为加法运算,ALU中无需集成减法器。
求补码的过程为什么是求反码再+1?
解:
比如 :-14=10001110
00001110各个位置取反得11110001,这两个数相加为1111111,那么取反再+1,再相加就为100000000
相关运算
移位运算
原码算术移位:
对于十进制——小数点后移,相当于乘;前移,相当于除;通过改变各个数码位和小数点的相对位置,从而能改变个数码位的位权。实现乘法除法。
定点整数算数右移:高位补0,低位舍弃,若舍弃位=0,则 整体÷
;否则会
丢失精度
定点整数算数左移:高位舍弃,低位补0,若舍弃位=0,则 整体*
;否则会
出现严重误差
反码的算数移位:
正数与原码一样
负数:右移:高位补1,低位舍弃
左移:低位补1,高位舍弃
补码的算数移位
正数与原码一样
负数:负数补码=负数反码末尾+1 这导致反码最右边的几个连续的1都因为进位而变成0,直到进位碰到第一个0为止
所以负数补码可以看成两部分,第一部分:最右边的1的左边同反码;第二部分:最右边的1及右边同原码
在进行移位的时候:
右移(同反码)
:高位补1,低位舍弃
左移(同原码)
:低位补0,高位舍弃
码制 | 添补代码 | 遵循:左移*2,右移÷2 | |
正数 | 原码、补码、反码 | 0 | |
负数 | 原码 | 0 | |
反码 | 1 | ||
补码 | 左移0 | ||
右移1 |
移位作用:
移位在计算机计算过程中有什么作用呢?可以实现算数乘法
比如:计算20*7
7=111B=
20*(
) 就相当于20不左移+20左移一位+20左移两位
逻辑移位
逻辑右移:高位补0,低位舍弃
逻辑左移:低位补0,高位舍弃
可以把逻辑移位看作对“无符号数”的算数移位
逻辑移位作用
每个颜色可以用不同的RGB值来表示
循环移位
进行移位的时候,移除的位补上空缺的位
可以通过循环移位完成大端/小端存储的转换
加减运算
原码的加法减法运算:
正+正——>绝对值做加法,结果为正,可能溢出
负+负——>绝对值减法,结果为负,溢出
正+负/负+正——>绝对值大的减绝对值小的,符号同绝对值大的数
补码的加减法运算
设机器字长为8位(含一位符号位),A=15,B=-24,求
,
=
发现两个正数相加为负数,说明发生了溢出,因为8bit可以表示的补码为-128~127
溢出判断
两个异号的数相加,结果绝对值一定比其中一个小
可以采用双符号位,正数符号为00,负数符号为11,加法运算后若符号位=01,则发生上溢;若双符号位10则发生下溢,;若两个符号位相同则未发生溢出
符号扩展
int——>long
正整数(原、反、补码的表示都一样):01011010
正整数(原、反、补码的表示都一样) | 01011010 | 00000000 01011010 |
负整数 | ||
原码 | 11011010 | 10000000 01011010 |
反码 | 10100101 | 11111111 10100101 |
补码 | 10100110 | 11111111 1010011 |
正小数(原、反、补码的表示都一样) | 0.1011010 | 0.1011010 00000000 |
负 小数 | ||
原码 | 1.1011010 | 1.1011010 00000000 |
反码 | 1.0100101 | 1.0100101 11111111 |
补码 | 10100110 | 1.0100110 00000000 |
定点数乘法运算
原码乘法
负数符号位单独计算,进行异或。
ACC:存放乘积高位
MQ:乘数、乘积低位
X:被乘数
MQ存放当前乘数最低位,若最低位为1,则ACC+X;否则ACC+0;然后ACC右移,并把多余的放到MQ里,MQ也右移。重复多次
最后用符号位的异或结果来代替符号位
补码乘法
MQ向右扩展一位,初始为0;ACC与X向左扩展一位,形成双符号位
定点数原码除法
ACC存储被除数和余数,MQ会存储商,X存储除数
恢复余数法
符号位单独处理,等于被除数与除数符号位异或的结果;数值位取绝对值进行除法
- MQ的最低位先写入1,之后ALU先进行[ACC]-[X]——>[ACC],这时候发现[ACC]的符号位是1,表示被除数小于除数;MQ的最低位改为0;[ACC]+[X]——>[ACC](恢复余数)
- ACC与MQ统一左移,ACC高位丢弃(左移就像在除法中最后一位添0接着除);
-
[ACC]+
——>[ACC],如此循环 - 最后进行符号位的单独处理
恢复余数的过程可以被优化:
如果相减的余数a是负的,那么需要加上除数的补码b,结果为a+b;结果左移做被除数,相当于乘2,即2(a+b);后又+[-除数的补码],最后结果是(a+b)*2-b;这样就不用恢复余数,直接商0,让余数左移一位加上除数绝对值。
若老余数是正的,商1,左移一位,减除数;若老余数是负的,商0,左移一位,加除数;
这就是
加减交替法,
是把恢复余数法的优化,把恢复余数这一步简化。
定点数补码除法
加减交替法
强制类型转换
定点整数用补码存储
-
short(2个字节)——>unsigned short 长度相同时, 符号数转换为无符号
其中short类型是用补码存储,比如:x=-4321 存储为 1110 1111 0001 1111
变为无符号数的话是不改变数据内容的,直接按照原码进行转换,unsigned short y=(unsigned short)x; 则y=61215
-
int->short 长整数变为短整数,是直接截断
int是4个字节,short是2个字节
int a=135537,a:0x000286a1
short b=(short)a; b:0x86a1 用16bit补码的形式进行解析,b=-31071
-
short->int 就是直接进行扩展,跟上面提到的符号扩展是一个原理