计算机组成原理与汇编语言

note①

相关概念

机器数:数字在计算机中的二进制表达形式,在二进制的最高位存放正或负符号,正数为0,负数为1

真值:带符号位的机器数对应的真正的数值

原码:符号位加上真值的绝对值

反码:正数の反码还是本身,而负数的反码:符号位不变,其余位按位取反

补码:反码+1


那么,为什么要引入反码和补码?

  • 人脑计算:我们会自动将符号位分开并进行计算

  • 电脑(计算机)计算:因为符号位也是0,1表示,在做计算时,计算机无法辨别哪些是符号位哪些是数值位。如果硬要让计算机认识的话也不是不行,但是这会使计算机的基础电路设计变得异常复杂(这是要累死设计计算机的人- -)

所以我们希望符号位也能参与到运算当中。另外我们都知道CPU只有加法器而没有减法器,这是为什么呢?我们小学就知道,减法是加法的逆运算(减去一个数等于加上那个数的负数),因此只要解决计算机的加法问题就好啦

At First…

原码君出来了,但是在运算中很快就发现了问题,比如一个正数和一个负数相加,就会出问题。比如1-1

1 - 1 = 1 + (-1) = [0000_0001]原 + [1000_0001]原 = [1000_0010]原 = -2 

And…

出现了原码君的儿子反码君,值得高兴的是,反码能够使得计算结果的真值正确,但是唯独在0这个值上栽了跟头

1 - 1 = 1 + (-1) = [0000_0001]原 + [1000_0001]原= [0000_0001]反 + [1111_1110]反 = [1111_1111]反 
= [1000_0000]原 = -0

0已经能用[0000_0000]原 表示了,现在又整出一个[1000_0000],没有意义啊这

Finally!

原码君的孙子aka反码君的孙子——补码君诞生了,他很完美地解决了这个问题:

1-1 = 1 + (-1) = [0000_0001]原 + [1000_0001]原 = [0000_0001]补 + [1111_1111]补 = [0000_0000]补
=[0000_0000]原 = 0

Besides…

除此之外,还可以用 [1000_0000]补 表示-128:

(-1) + (-127) = [1000_0001]原 + [1111_1111]原 = [1111_1111]补 + [1000_0001]补 = [1000_0000]补

-1-127的结果应该是-128,在用补码运算的结果中, [1000_0000]补 就代表-128。

注意,-128并没有原码和反码表示。

使用补码不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数,这就是为什么8位二进制使用原码或反码表示的范围为 [-127, +127],而使用补码表示的范围为 [-128, 127] 的原因。

因为机器使用补码,所以对于编程中常用到的32位int类型可以表示范围是 [-2^31, 2^31-1] ,因为第一位表示的是符号位,而使用补码表示时又可以多保存一个最小值。

note②