news 2026/7/6 15:11:50

《深入理解计算机系统》读书笔记01: 从入门到实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《深入理解计算机系统》读书笔记01: 从入门到实践

《深入理解计算机系统》学习指南:从入门到实践

作者: andylin02
学习章节: 全书概览
关键词: CSAPP; 计算机系统漫游; 编译系统; 存储层次结构; 进程; 虚拟内存; 抽象


《深入理解计算机系统》(Computer Systems: A Programmer’s Perspective,简称 CSAPP)被誉为计算机领域的圣经,是每个程序员深入理解底层系统的必读之作。它不仅涵盖了计算机系统的核心概念,还通过大量实验帮助读者在实践中巩固知识。

一、全书章节概览

本书共 12 章,大致可分为三大部分:

部分章节核心内容
第一部分第1-6章程序结构和执行:数据表示、汇编、处理器架构、性能优化、存储器层次结构
第二部分第7-9章在系统上运行程序:链接、异常控制流、虚拟内存
第三部分第10-12章程序间的交互和通信:系统级 I/O、网络编程、并发编程

第一章:计算机系统漫游— 通过跟踪hello.c程序的生命周期,宏观了解计算机系统全貌。
第二章:信息的表示和处理— 深入讲解整数、浮点数的二进制表示与运算,是理解计算机底层运算的基础。
第三章:程序的机器级表示— 学习汇编语言与机器代码,理解 C 语言程序在底层的执行方式。
第四章:处理器体系结构— 设计一个简单的处理器,理解指令执行的流水线机制。
第五章:优化程序性能— 学习代码优化技巧,理解编译器优化能力与局限。
第六章:存储器层次结构— 深入理解缓存(Cache)的工作机制与程序局部性原理。
第七章:链接— 学习静态链接、动态链接、符号解析、重定位等核心概念。
第八章:异常控制流— 理解进程、异常、信号、非本地跳转等机制。
第九章:虚拟内存— 深入剖析虚拟地址到物理地址的映射机制,理解分页、缺页处理等。
第十章:系统级 I/O— 学习 Unix I/O 模型与文件操作。
第十一章:网络编程— 了解网络编程基础、客户端-服务器模型。
第十二章:并发编程— 学习线程、同步、并发 bug 等并发编程核心概念。


二、关键代码示例

1. 程序编译的四个阶段示例

以下是完整的hello.c程序以及各个阶段的输出示例:

// hello.c#include<stdio.h>intmain(){printf("hello, world\n");return0;}

预处理阶段(.i 文件):

// hello.i (部分示意)#1"hello.c"#1"<built-in>"#1"hello.c"externintprintf(constchar*__restrict __format,...);intmain(){printf("hello, world\n");return0;}

汇编阶段(.s 文件):

; hello.s main: subq $8, %rsp movl $.LCO, %edi call puts movl $0, %eax addq $8, %rsp ret .LCO: .string "hello, world"

编译命令:

# 完整编译gcc-ohello hello.c# 分步执行四个阶段gcc-Ehello.c-ohello.i# 预处理gcc-Shello.i-ohello.s# 编译gcc-chello.s-ohello.o# 汇编gcc hello.o-ohello# 链接

编译系统由预处理器(cpp)、编译器(ccl)、汇编器(as)、链接器(ld)四个程序构成。

2. 大端/小端存储示例

// 字节序检测程序#include<stdio.h>typedefunsignedchar*byte_pointer;voidshow_bytes(byte_pointer start,size_tlen){size_ti;for(i=0;i<len;i++)printf("%.2x ",start[i]);printf("\n");}voidshow_int(intx){show_bytes((byte_pointer)&x,sizeof(int));}intmain(){intval=0x01234567;printf("int 0x01234567 在内存中的字节序: ");show_int(val);return0;}
  • 小端存储(如 Intel x86):最低有效字节在前,输出为67 45 23 01
  • 大端存储(如某些 IBM 系统):最高有效字节在前,输出为01 23 45 67

三、架构图与流程图

1. 编译系统流程图

┌─────────────────────────────────────────────────────────────────────┐ │ 编译系统流程图 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ hello.c ──→ 预处理器 ──→ hello.i ──→ 编译器 ──→ hello.s │ │ (文本) (cpp) (文本) (ccl) (汇编) │ │ │ │ │ ↓ │ │ hello ──←─────── 链接器 ──←─────── hello.o ──←─── 汇编器 │ │ (可执行) (ld) (目标文件) (as) │ │ │ │ 阶段说明: │ │ ▸ 预处理:处理 #include、#define 等预处理指令 │ │ ▸ 编译:C 语言 → 汇编语言 │ │ ▸ 汇编:汇编语言 → 机器指令(二进制) │ │ ▸ 链接:合并目标文件及库 → 可执行文件 │ │ │ └─────────────────────────────────────────────────────────────────────┘

2. 典型系统硬件组成

┌─────────────────────────────────────────────────────────────────────┐ │ 典型系统硬件组成架构图 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ CPU ┌──────────────────────────────────────────────────┐ │ │ │ │ 寄存器文件 │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ ▲ │ │ │ │ │ ↓ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ │ 算术/逻辑单元 (ALU) │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ ▲ │ │ │ │ │ ↓ │ │ └─────────┼──────────────────────┼───────────────────────────────┘ │ │ │ │ ↓ ↓ │ ┌─────────────────┐ ┌─────────────────┐ │ │ 高速缓存 │◄────►│ 主存 │ │ │ (Cache) │ │ (DRAM) │ │ └─────────────────┘ └─────────────────┘ │ ▲ ▲ │ │ │ │ └──────────┬───────────┘ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ 系统总线 │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ↓ ↓ ↓ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ I/O桥 │ │ 磁盘 │ │ 显示器 │ │ │ 控制器 │ │ 控制器 │ │ 适配器 │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ ↓ ↓ ↓ │ [键盘/鼠标] [磁盘] [显示器] │ └─────────────────────────────────────────────────────────────────────┘

系统硬件包括总线、I/O 设备、主存(DRAM)和处理器。总线是贯穿整个系统的电子管道,通常设计为传送定长的字节块(字)。

3. 存储器层次结构

┌─────────────────────────────────────────────────────────────────────┐ │ 存储器层次结构图 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ L0: 寄存器 │ │ ↑ (1个周期) │ │ L1: L1 高速缓存 (SRAM) │ │ ↑ (2-4个周期) │ │ L2: L2 高速缓存 (SRAM) │ │ ↑ (10-20个周期) │ │ L3: L3 高速缓存 (SRAM) │ │ ↑ (50-100个周期) │ │ L4: 主存 (DRAM) │ │ ↑ (数百个周期) │ │ L5: 本地磁盘 │ │ ↑ (数千万个周期) │ │ L6: 远程存储(网络) │ │ │ │ 核心思想:每一层作为下一层的"高速缓存",速度递减、容量递增 │ │ │ └─────────────────────────────────────────────────────────────────────┘

存储器层次结构的设计核心是局部性原理(时间局部性和空间局部性),将更小更快的设备作为下一层的缓存。

4. 计算机系统抽象层次

┌─────────────────────────────────────────────────────────────────────┐ │ 计算机系统抽象层次 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 应用程序 │ │ ↑ │ │ │ 软件 │ │ ↓ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 操作系统 │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ │ │ 进程 │ │ 虚拟内存 │ │ 文件 │ │ │ │ │ │ (处理器抽象) │ │ (内存抽象) │ │ (I/O设备抽象) │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ ↑ │ │ │ 硬件 │ │ ↓ │ │ 计算机硬件(处理器、内存、I/O设备) │ │ │ │ 抽象对应关系: │ │ ▸ 文件 → I/O 设备的抽象表示 │ │ ▸ 虚拟内存 → 主存和磁盘 I/O 设备的抽象表示 │ │ ▸ 进程 → 处理器、主存和 I/O 设备的抽象表示 │ │ ▸ 指令集架构 → 实际处理器的抽象 │ │ │ └─────────────────────────────────────────────────────────────────────┘

操作系统通过进程、虚拟内存和文件等抽象概念实现两大功能:防止硬件被失控应用程序滥用,并为应用提供统一的硬件控制接口。


四、第一章预告:计算机系统漫游

1.1 信息就是位 + 上下文

核心思想:计算机系统中的所有信息——包括磁盘文件、内存中的程序、用户数据和网络数据——都是由一串比特(bit)表示的。区分不同数据对象的唯一方法是读取时的上下文。

例如,相同的二进制序列1101001

  • 作为字符读取:ASCII 码 105 → 字符i
  • 作为整数读取:十进制的 105
┌─────────────────────────────────────────────────────────────────────┐ │ 信息 = 位 + 上下文 示意图 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 二进制比特序列: 1101001 │ │ │ │ │ ┌─────────────┼─────────────┐ │ │ ↓ ↓ ↓ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ ASCII 解码 │ │ 整数解码 │ │ 指令解码 │ │ │ │ 上下文 │ │ 上下文 │ │ 上下文 │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ ↓ ↓ ↓ │ │ 字符 'i' 整数 105 机器指令 │ │ │ │ → 同样的比特流,在不同的上下文中呈现出完全不同的含义! │ │ │ └─────────────────────────────────────────────────────────────────────┘

1.2 程序被其他程序翻译成不同格式

hello.c从源文件到可执行文件的转换过程:

# 编译命令unix>gcc-ohello hello.c
┌─────────────────────────────────────────────────────────────────────┐ │ hello.c (文本) │ │ │ │ │ ↓ 预处理器 (cpp) - 处理 #include 等预处理指令 │ │ hello.i (文本) │ │ │ │ │ ↓ 编译器 (ccl) - 翻译成汇编语言 │ │ hello.s (汇编文本) │ │ │ │ │ ↓ 汇编器 (as) - 翻译成机器指令 │ │ hello.o (二进制目标文件) │ │ │ │ │ ↓ 链接器 (ld) - 合并 printf.o 等库文件 │ │ hello (可执行二进制文件) │ └─────────────────────────────────────────────────────────────────────┘

1.3 处理器读并解释存储在主存中的指令

典型硬件组成
组件功能描述
总线贯穿系统的电子管道,在各部件间传递信息字节
I/O 设备系统与外界的通道(键盘、鼠标、显示器、磁盘)
主存临时存储设备,存放程序和程序处理的数据,逻辑上是线性的字节数组
处理器(CPU)解释/执行主存指令的引擎,核心是程序计数器(PC)
高速缓存更小更快的存储设备,作为处理器与主存之间的缓存层
程序执行流程
┌─────────────────────────────────────────────────────────────────────┐ │ hello 程序执行流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 1. shell 读取命令行 "hello" │ │ ↓ │ │ 2. shell 调用加载器,将 hello 文件中的代码和数据复制到主存 │ │ ↓ │ │ 3. 处理器开始执行 main 程序中的机器语言指令 │ │ ↓ │ │ 4. 指令将 "hello, world\n" 字符串从主存复制到寄存器 │ │ ↓ │ │ 5. 寄存器将字符串复制到显示设备(经过存储器映射 I/O) │ │ ↓ │ │ 6. 屏幕上显示 "hello, world" │ │ │ │ 💡 关键技术:DMA(直接存储器存取),数据可直接从磁盘到达主存, │ │ 无需经过处理器 │ │ │ └─────────────────────────────────────────────────────────────────────┘

1.4 操作系统管理硬件

操作系统实现两个基本功能:

  1. 防止硬件被失控的应用程序滥用
  2. 向应用程序提供简单一致的硬件控制机制

操作系统通过三个基本抽象实现这些功能:

抽象概念抽象的对象说明
文件I/O 设备将磁盘、键盘等设备统一抽象为文件
虚拟内存主存 + 磁盘 I/O为每个进程提供独占主存的假象
进程处理器 + 主存 + I/O 设备操作系统对正在运行的程序的一种抽象

1.5 Amdahl 定律与并发并行

Amdahl 定律:当我们对系统的某个部分进行加速时,其对系统整体性能的影响取决于该部分的重要性与加速程度。这提醒我们优化应聚焦于关键瓶颈。

并发与并行的区别

  • 并发:逻辑上的同时,强调一段时间内处理多个任务
  • 并行:物理上的同时,强调多核处理器真正同时执行

1.6 本章学习收获

第一章的核心价值在于建立计算机系统的宏观认知,包括:

  • ✅ 程序的整个生命周期(编写 → 编译 → 链接 → 加载 → 执行)
  • ✅ 编译系统的四个阶段及各阶段作用
  • ✅ 系统硬件的核心组成(总线、I/O 设备、主存、处理器、高速缓存)
  • ✅ 存储层次结构与局部性原理
  • ✅ 操作系统提供的抽象层(进程、虚拟内存、文件)
  • ✅ Amdahl 定律与并发并行基本概念

这些概念将在后续章节中深入展开。本书从上层程序出发,由上至下剖析和串联了每一个环节,帮助读者构建完整的计算机系统知识体系。


五、学习建议

1. 学习资源汇总

资源类型推荐内容
官方教材《深入理解计算机系统》第 3 版
在线课程CMU 15-213(本书作者授课的原版课程)
配套实验Data Lab、Bomb Lab、Attack Lab、Cache Lab、Shell Lab、Malloc Lab、Proxy Lab 等 7 个经典实验
开源代码GitHub 上的csapp实验代码库(包含简易 shell 程序、动态内存分配器等)

2. 学习路线

第一阶段:打好基础 ├── 第1章:计算机系统漫游(建立宏观概念) ├── 第2章:信息的表示和处理(二进制基础) └── 第3章:程序的机器级表示(汇编基础) 第二阶段:深入底层 ├── 第4章:处理器体系结构 ├── 第5章:优化程序性能 └── 第6章:存储器层次结构 + Cache Lab 第三阶段:系统核心 ├── 第7章:链接 ├── 第8章:异常控制流 + Shell Lab ├── 第9章:虚拟内存 + Malloc Lab 第四阶段:应用拓展 ├── 第10章:系统级 I/O ├── 第11章:网络编程 + Proxy Lab └── 第12章:并发编程

3. 实验推荐顺序

  1. Data Lab— 熟悉整数和浮点数的位级表示(入门级)
  2. Bomb Lab— 学习汇编语言和 GDB 调试
  3. Attack Lab— 理解代码注入和缓冲区溢出攻击
  4. Cache Lab— 深入理解缓存机制
  5. Shell Lab— 实现简易 shell 程序,学习进程管理和信号处理
  6. Malloc Lab— 实现动态内存分配器
  7. Proxy Lab— 实现 HTTP 代理服务器

阅读建议:本书每章前言都会从程序员角度分析"为什么要学这些知识",然后正文清晰地阐述答案,建议认真阅读每章前言。


六、总结

《深入理解计算机系统》是一本将理论与实践完美结合的计算机系统经典著作。通过阅读本书和完成配套实验,你将能够:

  • 🎯 构建完整的计算机系统知识体系
  • 🎯 编写更高效、更安全、更可移植的程序
  • 🎯 快速定位和解决程序中的性能问题
  • 🎯 理解编译、链接、加载等底层机制
  • 🎯 掌握网络编程和并发编程的核心技术

后续章节将逐步深入,敬请期待!


本文为个人学习笔记,仅用于知识分享。如有错误,欢迎指正。
👍🏻 点赞 + 收藏 + 分享,让更多开发者看到这篇深度解析!❤️ 如果觉得有用,请给个赞支持一下作者!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 15:11:02

【Atlas】如何配置 Atlas 的日志级别和日志路径?

Apache Atlas 2.4.0 日志体系深度调优指南&#xff1a;从配置到故障定位的全链路实践 用户问题原文&#xff1a;“如何配置 Atlas 的日志级别和日志路径&#xff1f;” 本文将围绕这一运维基石问题&#xff0c;进行体系化、原理级、生产可落地的深度解析。我们将从一次因日志级…

作者头像 李华
网站建设 2026/7/6 15:09:43

分支循环语句—— 从懵圈到上手的真实感悟

一、核心知识点数理 1、分支语句 条件判断后执行不同代码。像if-else&#xff0c;单条件用if(条件){...}&#xff0c;双选择加else{...}&#xff0c;多条件用else if&#xff1b;switch适合判断整型或字符型常量&#xff0c;用case匹配&#xff0c;break跳出&#xff0c;defaul…

作者头像 李华
网站建设 2026/7/6 15:08:03

新手友好!基于零代码平台学生用户画像-考勤主题标签构建全流程演示

一、实验背景 1.1实验目的 基于数智教育大赛数据集&#xff0c;设计并搭建学生多维度考勤统计助睿 ETL 转换流程&#xff0c;完整覆盖数据接入、关联匹配、字段衍生、指标聚合、数据落地全 ETL 处理链路。针对校园考勤人工统计效率低下、统计口径不统一等痛点开展专项解决&am…

作者头像 李华
网站建设 2026/7/6 15:04:26

13DOF传感器与PIC24微控制器在嵌入式导航中的应用

1. 为什么选择13DOF与PIC24HJ256GP610组合在嵌入式定位导航领域&#xff0c;传感器和主控芯片的选型直接决定了系统性能上限。13DOF&#xff08;13自由度&#xff09;传感器模块之所以成为当前中高端定位方案的首选&#xff0c;是因为它集成了三轴加速度计、三轴陀螺仪、三轴磁…

作者头像 李华