「深入理解计算机系统」学习笔记(第二章)

本文主要是《深入理解计算机系统》第二章(信息的表示和处理)的学习笔记。主要依据 B 站 UP 主九曲阑干对 CSAPP 的 中文讲解

本章主要涉及如下知识点:

  1. 信息存储
  2. 整数表示
  3. 整数运算
  4. 浮点数

信息存储

在计算机中,内存可以视为一个大数组,数组的元素由一个个字节组成。每一个字节都由一个唯一的数字表示,称为地址。地址的集合称为 虚拟地址空间

vap.png

字节

一个字节是由 8 个位组成,一个位的取值只为 0 或 1。

二进制十进制
000000000
11111111255

我们将使用二进制表示数字的方式称为 位模式

十六进制

因为使用二进制表示比较冗长,而十进制与二进制之间的转换较为麻烦。所以引入了十六进制。

十六进制使用 10 个数字(0123456789)和 6 个字母(ABCDEF)表示。

在 C 语言中,使用 0x 开头表示一个十六进制。

十进制十六进制二进制
000000
110001
220010
330011
440100
550101
660110
770111
881000
991001
10A1010
11B1011
12C1100
13D1101
14E1110
15F1111

字长

字长决定了虚拟地址空间最大值。

字长虚拟地址空间备注
w 位0 ~ $2^w-1$
32 位0 ~ $2^{32}-1$4GB
64 位0 ~ $2^{64}-1$16EB

C 语言各个数据类型大小如下表所示:

type.png

地址和字节排布

order.png

目前,大部分使用的 PC 机使用小端法排布。

字符串表示

C 语言中字符串被定义为以 NULL 结束的字符数组。例如,字符串 abcde 虽然只有 5 个字符,但长度为 6。

const char *s = "abcde";

string.png

NULL 在 C 语言中对应 0x00,该字符串在内存中以十六进制表示为:

61  62  63  64  65  00

C 语言的位级运算

逻辑非:

~
01
10

逻辑与:

&01
000
101

逻辑或:

| | | 0 | 1 | |—|—|—| | 0 | 0 | 1 | | 1 | 1 | 1 |

逻辑异或:

^01
001
110

C 语言的逻辑运算

逻辑运算中,所有非 0 都表示 true,0 表示 false。

表达式结果备注
0x410x00
!0x000x01
!!0x410x01
0x69 && 0x550x01
0x690x55
a && 5 / a当 a 为 0 时,不继续判断 5 / a

C 语言的移位运算

对于二进制数 01100011

左移一位:11000110

左移两位:10001100

逻辑右移丢弃最右端 n 位,并在最左端补 n 个 0。

算术右移当最高位为 0 时,右移且在最左端补 0;最高位为 1 时,在最左端补 1。

大部分编译器对于有符号数采用算术右移,对于无符号数采用逻辑右移。

整数表示

C 语言支持多种整型数据类型,以 64 位操作系统为例。

C 数据类型最小最大字节
char$-2^7$$2^7-1$1
unsigned char0$2^8-1$1
short$-2^{15}$$2^{15}-1$2
unsigned short0$2^{16}-1$2
int$-2^{31}$$2^{31}-1$4
unsigned int0$2^{32}-1$4
long$-2^{63}$$2^{63}-1$8
unsigned long0$2^{64}-1$8
int32_t$-2^{31}$$2^{31}-1$4
uint32_t0$2^{32}-1$4
int64_t$-2^{63}$$2^{63}-1$8
uint64_t0$2^{64}-1$8

需要特别注意,long 类型取值范围与机器字长有关。在 32 位机器上,long 为 4 字节;在 64 位机器上,long 为 8 字节。

无符号数编码

对于向量 $x = [x_{w-1}, x_{w-2}, \cdots, x_1, x_0]$,

$B2U_w(x) = x_{w-1}\cdot 2^{w-1} + x_{w-2}\cdot 2^{w-2} + \cdots + x_1\cdot 2^1 + x_0\cdot 2^0 = \sum^{w-1}_{i=0}{x_i2^i}$

补码编码

对于向量 $x = [x_{w-1}, x_{w-2}, \cdots, x_1, x_0]$,

$B2T_w(x) = x_{w-1}\cdot -2^{w-1} + x_{w-2}\cdot 2^{w-2} + \cdots + x_1\cdot 2^1 + x_0\cdot 2^0 = -x_{w-1}\cdot 2^{w-1} + \sum^{w-2}_{i=0}{x_i2^i}$