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

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

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

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

信息存储

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

字节

一个字节是由 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 语言各个数据类型大小如下表所示:

地址和字节排布

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

字符串表示

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

1
const char *s = "abcde";

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

1
61  62  63  64  65  00

C 语言的位级运算

逻辑非:

~
01
10

逻辑与:

&01
000
101

逻辑或:

0
001
111

逻辑异或:

^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}\)