读书笔记——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 | +----+----+----+----+ |
大端法:
1 | +----+----+----+----+ |
移位运算
移位
运算就是向左移、向右移。向左移(<<)都是舍弃最高位,右端用0来补。而右移就出现了两种形式:逻辑
右移(logical)和算术
右移(arithmetic)。逻辑右移
是在左端用0来补位。算术右移
是在左端用1来补位。其中,算术右移对有有符号整数数据的运算非常有用。对于无符号数据,右移必须是逻辑的。
补码编码
有符号数的表示方法比较常见的是补码
(two’s-complement)形式。最高有效位是符号为。如果是0就是正数,1是负数。这个最高有效位算是负权(negative weight),权重为,其中w为位数。书中Figure 2.12
直白的展示了正负数的表示。
还有其他的表示方法,比如反码(Ones’Complement)、原码(Sign-Magnitude)。
有符号数和无符号数之间的转换
书中写的比较详细,可以参考Figure 2.15
,Figure 2.16
,Figure 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上有我的一些解答。希望大家能提出宝贵的建议。