CPU是如何执行程序的?
1、我们先来看下两位全加器
A = 01B = 1H
B = 11B = 3H
A + B = 1 + 3 = 4 = 100B
为了方便更多比特位的运算,我们使用内部集成8个全加器芯片74283来运算
DATA1 = 0000 0101B = 5H
DATA2 = 0000 1010B = 10H
SUM = 0000 1111B = 15H
2、那么数字电路是如何进行加减乘除运算的? 注意:我们这里不考虑一些特殊的情况,我们8位数最大能表示的数为255,所以只考虑数值小于255的情况,更深入的探讨大家可以去寻找更专业的资源学习。加法运算:假设我们要进行8+13运算:十进制运算:8+13= 21;二进制运算:0000 1000 + 0000 1101 = 00010101;
减法运算: 加法是进位,减法需要考虑的则是借位,小学时对加减法的经验是这样的,但是计算机不是这么处理的。计算机只有加法,没有减法。那么 int a = b - c 是怎么得出来结果的呢?首先要了解一个概念——补码。 计算机中对于有符号数,用最高位作为符号位,“0” 代表 “+” ,“1” 代表 “负号-” ;其余数位用作数值位,代表数值。比如 Byte 类型的取值范围为 -128 ~ 127。其中,表示数值的只有 7 位,首位表示正负。 补码规定,正数和 0 的补码就是其原码(原码、反码的定义这里就不多赘述),负数的补码是其正数的原码取反再加 1 。举个例子,求负 -10 的补码:十进制 10 的原码(按 8 位举例)为 0000 1010,其反码为 1111 0101,取反后再加 1 即为其补码1111 0110。因此,负10 的补码为 1111 0110。不知道写到这里,大家有没有发现什么端倪?我们再回到减法计算来,a = b - c 实际上等同于a = b + ( -c )。情形1,减数>被减数- 12 - 5= 0000 1100 + 1111 1011= (1)0000 0111= 7 括号里为进位,因为只有 8 位,所以高于 8 位的进位要去掉。
- (-5 )二进制: 000 0101;
- 反码:1111 1010;
- 补码 = 反码+1:1111 1011
- 最终通过加入反相电路和加1电路得到的最终结果,进位去掉后为0000 0111换算成10近制就是7
情形2,减数>被减数 - 再来计算下7 - 9= 0000 0111 + 1111 0111= 1111 1110= -2
- (-9)二进制:0000 1001,
- 反码:1111 0110,
- 补码:1111 0111
- 然后得到的是负数,我们又要把它反回来
- 补码-1:1111 1110-1 = 1111 1101
- 反码反过来:0000 0010
- 0000 0111 + 1111 1101
通过这两个例子是不是就清楚了计算机是如何计算减法的了?
乘法运算:
通过说减法,我们是不是对乘法也有一定的启发了呢?乘法其实就是循环的加法。比如 5 * 3 实际上就是 5 + 5 + 5。貌似就说完了。实际上不仅仅如此的。现在有一个电子器件叫做乘法器,其可以实现二进制的乘法、除法等运算。我们同样以 5 * 3 做为例子,讲解一下乘法器计算乘法的流程。
- 5 * 3 = 0000 0101 * 0000 0011
- 第一步:5 + 5 = 10
- 00000 0101 + 0000 0101 = 0000 1010
- 第二步:10 + 5 = 15
- 0000 0101 + 0000 1010 = 0000 1111
小提示:当然也可以通过移位电路来运输也是可以的,这里就不举例子了 虽然CPU中有乘法器,但是我们发现实际的最终操作流程还是加法和位移操作计算的乘法运算。我们写的代码中的乘法到底是用乘法器运算还是转化成加法运算,我们也并不太确定,有些编译器编译的时候会对代码进行优化,选取最优的一种算法来计算结果。除法运算:除法可以通过减法来实现,比如 10 / 3 等价于 10 一直减 3 直到被减数小于 3 ,减了 3 次,那么 10 / 3 的结果就为 3 了,余数为减完剩下的值 1 。其实上面已经提到了乘法器,除法的原理同样也类似(这里不说浮点数的除法,只说整数的除法),但是稍微复杂一点。同样我们举个例子来说明一下。- 10 / 3 = 000 1010 / 0000 0011
- 第一步:10 - 3 = 7
- 000 1010 - 0000 0011 = 0000 0111
- 第二步:7 - 3 = 4
- 0000 0111 - 0000 0011 = 0000 0100
小提示:这里只是展示其中一种除法运算,大家可以去思考其他方式的除法运算,比如说使用移位方式。 然后我们再来看一个完整的CPU计算电路
感兴趣的小伙伴可以参考下面这个链接:
http://www.buthowdoitknow.com/but_how_do_it_know_cpu_model.html
然后这里面我们发现复杂的运算会产生中间数据,比如说乘法,除法,要计算好几次才能得到结果,所以我们就需要寄存器来临时存储这些数据,这样我们就可以计算了。
|