读书笔记——CSAPP第二章

CSAPP(Computer Systems: A Programmer’s Perspective ),中文书名为深入理解计算机系统。这本书的好不需多言。为了锻炼英文阅读能力,我特地买的是英文原版。第一章比较简短,简单的从一段Hello World C程序,慢慢深入计算机底层的运行机制。可以说这一章就是本书的框架。以下是从第二章开始,记录了我遇到的困惑,一些简单的就不再介绍,书上已经写的很详细。

第一部分 程序结构和执行

信息的表示和处理

信息储存

现代计算机存储和处理的信息以二值信号表示。其中,有三种重要的数字表示。无符号(unsigned)编码基于传统的二进制表示法,表示 大于或者等于零的数字。补码(two’s-complement)编码是表示有符号整数的最常见的方式,有 符号整数就是可以为正或者为负的数字。浮点数(floating-point)编码是表示实数的科学记数法的以二为基数的版本。

大多数计算机使用 8 位的块,或者字节(byte),作为最小的可寻址的存储器单位。机器级程序将存储器视为一个非常大的字节数组,
称为虚拟存储器(virtual memory)。存储器的每个字节都由 一个唯一的数字来标识,称为它的地址(address),所有可
能地址的集合称为虚拟地址空间(virtual address space)。

每台计算机都有一个字长(word size),指明整数和指针数据的标称大小(nominal size)。字长决定的最重要的系统参数就是虚拟地址空间的最大大小。对于一个字长为 w 位的机器而言,虚拟地址的范围为 0 ~ ,程序最多 访问 个字节。

在寻址和字节顺序这一块,有一些需要注意的地方。首先是位表示一个数。存在两种表示方法。小端法(little endian),最低有效字节在最前面的方式。相反,大端法(big endian),最高有效字节在最前面的方式。

举个例子,12 34 56 78

小端法:

1
2
3
4
5
+----+----+----+----+

|0x78|0x56|0x34|0x12|

+----+----+----+----+

大端法:

1
2
3
4
5
+----+----+----+----+

|0x12|0x34|0x56|0x78|

+----+----+----+----+

移位运算

移位运算就是向左移、向右移。向左移(<<)都是舍弃最高位,右端用0来补。而右移就出现了两种形式:逻辑右移(logical)和算术右移(arithmetic)。逻辑右移是在左端用0来补位。算术右移是在左端用1来补位。其中,算术右移对有有符号整数数据的运算非常有用。对于无符号数据,右移必须是逻辑的。

补码编码

有符号数的表示方法比较常见的是补码(two’s-complement)形式。最高有效位是符号为。如果是0就是正数,1是负数。这个最高有效位算是负权(negative weight),权重为,其中w为位数。书中Figure 2.12直白的展示了正负数的表示。

还有其他的表示方法,比如反码(Ones’Complement)、原码(Sign-Magnitude)。

有符号数和无符号数之间的转换

书中写的比较详细,可以参考Figure 2.15Figure 2.16Figure 2.17辅助理解。

扩展一个数字的位表示

将一个无符号数转为一个更大的数据类型,只需简单的在表示的开头添加0,这种运算称为零扩展(zero extension)。将一个补码数字转换为一个更大的数据类型可以执行符号扩展(sign extension),规则是在表示中添加最高有效位的值的副本。

浮点数

本书提到了IEEE浮点表示。IEEE浮点标准的形式来表示一个数:

  • 符号(sign) s 决定这个数是负数(s=1)还是正数(s=0),而对于数值 0 的符号位解释作为特殊情况处理。

  • 尾数(significand) M 是一个二进制小数,它的范围是 1 ~ 2 - ε,或者是 0 ~ 1 - ε。

  • 阶码(exponent) E 的作用是对浮点数加权,这个权重是 2 的 E 次幂(可能是负数)。 将浮点数的位表示划分为三个字段,分别对这些值进行编码:

    • 一个单独的符号位 s 直接编码符号 s。

    • k位的阶码字段exp=)…)编码阶码E。

    • n 位小数字段 frac = )… 编码尾数 M,但是编码出来的值也依赖于阶码字段的值是否等于 0。

其中,浮点数32位的阶码有8位,64位的阶码有23位。

对于规格化的值,非规格化的值,特殊值的计算,还需多看书中的知识点。IEEE 754表示法,CSAPP对阶码E的求解和学校教材的不同,这里我有点疑惑,最后还是决定相信CSAPP。

舍入

figure 2.36 展示了4中舍入方法,可以简单看看作为了解。

小结

这一章节学习了数的表示。很多人会感觉这块知识感觉没什么用,写个程序用不到这个呀。其实错了,这恰恰是编程中基础的基础。理解计算机是如何工作的,如何处理数的,才能优化程序,减少程序中可以出现的因为对数的操作不当引起的bug。后面的作业和配套的lab正在做。Github上有我的一些解答。希望大家能提出宝贵的建议。