《深入理解计算机系统》--前言
目标
了解程序在计算机系统上的实现细节,在大脑中构造一个层次性的计算机系统:从最低层的数据在内存中的表示,到流水线指令的构成,到虚拟存储器,到编译系统,到动态加载库,到最后的用户态应用。在脑海中建立起数据或指令流图。
从程序员的角度看:
高级语言—>中间格式(如汇编语言)【描述计算机解释和执行中间格式的程序,是系统的哪一部分影响执行效率】
顺便给出了C语言和汇编语言的编程和阅读技巧。
主要内容
计算机体系结构(高级硬件设计)与编译器、操作系统的交互:
- 数据表示
- 汇编语言和汇编级计算机体系结构
- 处理器设计
- 程序的性能度量和优化
- 程序的加载器、连接器、编译器
- I/O层次结构、存储器层次结构
- 虚存
- 外存
- 中断、信号、进程控制
本书是一座桥梁,连接着计算机系统结构、处理器、操作系统、编译器、网络、并发编程。
方法
理解概念+动手实践。
计算机系统就像自然界的生态环境,对每一个部件的设计都要求它能容发卡地和系统内其它部件和平相处。因此我们不能站在一个微观视角去看待系统部件设计是否最右,而要从宏观观察思考。
术语翻译
-
directive
这个单词多用来描述C语言中类似**#include的语句,或汇编语言中类似.pos的语句。这个单词称作指令比较恰当,起着指导或引导的作用。但是,instruction也时有出现,且语义比directive更强势。因此最终将directive翻译为命令**。 -
operation
此单词遍布全书,意思是:”操作“和”运算“。这种划分不是绝对的,在第2章(涉及大量数学描述)中主要翻译为”运算“,在其他章节中主要翻译为”操作“。 -
memory & storage
不能简单把memory习惯解释为”内存“。本书认为memory可以是不同容量、成本和访问时间的存储设备。过去我们认识的memory只是DRAM。
从memory和storage这两个单词的中文意思来看, memory是”存储器“,而storage是”存储,存储器“。memory更多地以名词出现,描述一个静态的物理设备,storage除了可以作为名词出现外,还有动词形式(store,storing,stored)。所以取memory的中文意思为”存储器“,取storage的中文意思为”存储“。 -
hazard
直用最可。也称”险象,冒险“。 -
timer
”“定时器,计时器”。尽管这两个意思可以描述一个现象:间隔一段世家后产生一个时间,但是两者之间有所区别,”定时器“趋向于静态性,在其他章节翻译;“计时器”趋向于动态性,在第9章(主要描述系统评价)中翻译。 -
local
“本地,局部”。根据上下文选用不同的解释。
准备知识
本书重点:执行X86-64机器代码的系统
我们考虑:在X86-64如何在Linux系统上运行C程序。本书内容几乎直接适用于“类Unix”操作系统。
- Windows系统:安装虚拟机环境(如 VirtualBox,VMWare),以便为 Linux操作系统(客户OS)编写的程序能在Windows系统(宿主OS)上执行。
- 了解C和C++
- 所有源程序代码都可以从 csapp. cs. cmu. edu 上的 CS:APP 主页上获取。
目录
1.计算机系统漫游
通过研究 “hello, world”这个简单程序的生命周期,介绍计算机系统的主要概念和主题。
2.信息的表示和处理
讲述计算机的算术运算,重点在对程序员有影响的无符号数和补码特性。
考虑数字如何表示,才能确定对于一个给定字长,其可能的编码范围。
探讨有符号和无符号数字之间类型转换的效果,阐述算术运算的数学特性。(菜鸟级程序员经常很惊奇地了解到用补码表示的两个整数的和或者积可能为负)
另一方面,补码的算术运算满足很多整数运算的代数特性,因此,编译器可以很安全地把一个常量乘法转化为一系列的移位和加法。我们用C语言的位级操作说明布尔代数的原理和应用。
从两方面讲述IEEE标准浮点格式:一,如何用它表示数据;二,浮点运算的数学属性
对计算机算术运算有深刻理解是写出可靠程序的关键。比如,程序员和编译器不能用表达式(x-y<0)来替代(x<y),因为前者可能会产生溢出。也不能用(-y<-x)来替代,因为在补码表示中负数和正数的范围是不对称的。算数溢出是造成程序错误和安全漏洞的一个常见根源(然而很少有书从程序员的角度来讲述计算机算术运算的特性。0
3.程序的机器级表示
教读者如何阅读由C编译器生成的X86-64机器代码。
说明为不同控制结构(条件、循环、开关语句)生成的基本指令模式;
讲述过程的实现,包括栈分配、寄存器使用惯例、参数传递;
讨论不同数据结构(如结构、联合、数组)的分配和访问方式;
说明实现整数和浮点数 的算术运算的指令;
以分析程序在机器级的样子为途径,来理解常见的代码安全漏洞(如缓冲区溢出),以及理解编译器、OS和程序员可以采取的减轻这些威胁的措施。