【读书笔记】CSAPP第二章
信息的表示和处理
-
信息存储
-
- 计算机字长
- 寻址和字节顺序
- 位运算
-
整数表示
-
-
无符号数编码
-
有符号数编码
-
- 补码编码
-
有符号数与无符号数转换
-
拓展数字位
-
-
整数运算
-
浮点数
-
- IEEE浮点表示
-
- 1,规格化的值
- 2,非规格化的值
- 3,特殊值
- 舍入和运算
-
总结
信息存储
上章曾提到,信息就是位+上下文,计算机存储的信息在底层无非就是01序列,因此二进制是计算机存储、编码和操作信息的核心。
计算机使用8位的块作为一个字节(byte) ,代替单独的位作为最小可寻址的内存单元 。而内存的地址是基于虚拟内存(virtual memory) 的抽象概念(第九章),将各种存储设备结合起来提供一个直觉上统一的字节数组。
计算机字长
计算机字长,也就是我们平时常见的说法:32位机、64位机,这里的32和64就是计算机的字长(word size) ,代表指针数据的标称大小(指针的长度),即上面说的虚拟内存地址的编码的字长。
比如w=32位字长的机器,它的可寻址空间范围是0~2w -1,也就是说字长决定虚拟地址空间的最大大小。类似于9位十进制编码的qq号,它的寻址空间就是从0到999999999,每个空间对应一个用户(字节)
寻址和字节顺序
所有的程序对象都是一个字节序列,对于跨越多字节的对象,比如4个字节的int型变量,它在机器上存储为连续的字节序列,它的地址就是它所跨域字节中最小的地址。关于这些字节在内存中的排列规则,根据机器类型的不同分为大端法和小端法,比如0x01234567
大端法
0x100 0x101 0x102 0x103 … 01 23 45 67 … 小端法
0x100 0x101 0x102 0x103 … 67 45 23 01 …
位运算
将在二元集合{0,1}上定义的布尔运算拓展到位向量,就是位级布尔运算,它的一个常见用法就是实现掩码操作,对控制信号进行使能或屏蔽。
整数表示
计算机中的整数也是位的一种编码,根据编码方式的不同可以分为两种,一种可以表示非负数即无符号数 ,另一种可以表示负数、零和正数即有符号数
无符号数编码
直觉上可理解为所见即所得,对于w位的无符号整数,它的每一位都是数字值的一部分,因此无符号数编码具有从位到数值一一对应的关系,即双射 。
有符号数编码
面向需要表示负数值的场景,将最高位作为符号位。此时如果按照无符号编码直观上的逻辑,符号位表示正负然后其余位表示2的对应次幂:
对于8位编码而言,它的表数范围从11111111 ~ 01111111,也就是-127 ~ +127,然而此时10000000和00000000即-0和+0都表示数字0,此时编码不具备唯一性 ,不再是双射一一对应的关系
为了能够保证有符号数编码的唯一性 ,我们引入补码编码
补码编码
与原码表示不同,补码表示中最高位符号位也设置了权重,为-2w-1。此时对于非负数的表示和原码相同,而符号位为1时,映射需加上这个特殊的权重值:
比如4位补码1111表示-23+22+21+20=-8+4+2+1=-1,同理1000表示-8,数字0被0000唯一表示。
此时对比8位原码编码,补码的8位编码的表数范围就变成了-128~+127,同时这个编码方式具有从位到数值一一对应的关系,即双射 。
有符号数与无符号数转换
由于编码方式的不同,相同的位向量可能会有不同的解释。当符号位为0时,两种编码方式所得结果相同;当符号位为1时,无符号数为将该位解释为2w-1,而补码表示会将其作为-2w-1权重,中间相互转换产生的差值就是2w,因此

同理

其中Tmax表示补码表示的最大值。
拓展数字位
这里拓展指不同字长间的拓展,比如从short到int
无符号数拓展,直接开头加0,称为零拓展(zero extension)
有符号数拓展,开头拓展符号位,成为符号拓展(sign extension)
整数运算
略,溢出导致截断操作,截断操作为模运算
浮点数
至此关于数字的表示我们有了无符号和有符号整数编码,此时还有两个问题:
(1)小数的表示(2)大数字所占用位数
第一个问题,我们如何在计算机通过编码存储小数,按照常规思路关键是对于小数点的规定:比如我们想规定32位存储小数编码,那么我们就需要告诉计算机这个位向量哪部分解释为整数哪部分解释为小数,即规定小数点的位置。我们可以随便定义第0位作为符号位,第1到15位作为整数位,默认小数点位置紧跟其后,第16到31位作为小数位。这种表示法和整数编码一致,称为定点表示法 ,也就是小数点的位置是固定的。
这样的表示法是有缺陷的,在相同的长度下因为分别表示整数和小数,会使这种编码的表数范围和精度都比较小,书中也列举了飞毛腿导弹因内置时钟的小数表示精度问题导致人员伤亡的例子。
在定点表示法下为了提高精度,就需要提高编码所占用的位数,这也带来了和整数编码相同的第二个问题:位数占用,除了精度之外在一定位数下也无法表示非常大的数字。因此浮点数的编码设计就应运而生
IEEE浮点表示
在浮点编码下位被定义(解释)为3个部分:符号s(sign) 、阶码E(exponent) 和尾数M(significand) ,在这个标准下数为:
V=(-1)^s*M*2^E
对于单精度浮点数的位字段:
31 30… 22… s exp frac 单精度浮点数exp字段为8位,frac字段为23位;双精度浮点数exp字段为11位,frac字段52位
可以看出,二进制浮点数类比于十进制科学计数法,对尾数和指数分别进行编码。根据exp的值,被编码的值可以分为三种情况:
1,规格化的值
exp的位既不为全0也不为全1,此时阶码E=exp-Bias ,其中Bias是2k-1-1的偏置值,对于单精度k=8偏置值为127。exp被解释为无符号整数,而阶码则被解释为以偏置表示的有符号整数,其表数范围(单精度)为-126~+127。此时尾数被定义为M=1+frac ,即隐含的开头1(implied leading 1)。
阶码E之所以选择偏置编码表示有符号而不是直接通过exp补码表示有符号,是因为可以相比补码更方便的实现比较、对阶操作。
2,非规格化的值
exp为全0,此时阶码E=1-Bias ,对于单精度浮点数E=-126,尾数M=f 不包含开头1。取这个阶码值的非规格化数的存在:
(1)提供了表示数值0的方法,因为此时尾数不包含开头1
(2)提供了规格化数负数最大值到正数最小值这个区间内的数值,也就是非常接近于0.0的数,并且E=1-Bias与规格化值平滑相连,使其间数值均匀分布(逐渐下溢gradual underflow)
3,特殊值
exp为全1,此时当尾数为全0时,其值根据符号位表示正无穷或负无穷,用来表示溢出的情况;当尾数位非全0时,其值表示NaN(Not a Number)的结果
舍入和运算
略
总结
本章介绍了信息的表示形式,也就是字节序列的编码方式。信息就是位+上下文,根据上下文的不同,字节序列会被解码为指令、字符串、整数、实数等。目前已经了解了字符串、整数和实数的编码方式,下一章会从指令入手学习程序的编码,即机器指令对于人类可读的表示:汇编。
