计算机科 学 丛书 华章较育 P Pearson 原书第3版 深人理解计算机系统 兰德尔E.布莱恩特(Randal E.Bryant) 【关] 卡内基-御降人学 大卫R.奥哈拉伦(David R.O'Hallaron) 卡内基-降人学 龚奕利贷连译 Computer Systems A Programmer's Perspective Third Edition THIRD EDITION COMPUTER SYSTEMS A PROGRAMMER'S PERSPECTIVE BRYANT·O'HALLARON 机械工业出版社 China Machine Press
作者简介 兰德尔E.布莱恩特 (Randal E.Bryant) 1981年于麻省理工学院获得计算机博士学位, 1984年至今一直任教于卡内基-梅隆大学。现任卡 内基一梅隆大学计算机科学学院院长、教授,同时 还受邀任教于电子和计算机工程系。他从事本科生 和研究生计算机系统方面课程的教学近40年。他和 O'Hallaron教授一起在卡内基-梅隆大学开设了15- 213课程“计算机系统导论”,该课程即为本书的基 础。他还是ACM院士、IEEE院士、美国国家工程院 院士和美国人文与科学研究院院士。其研究成果被 Intel、.IBM、Fujitsu和Microsoft等主要计算机制造商 使用,他还因研究获得过Semiconductor Research Corporation、ACM、IEEE颁发的多项大奖。 大卫R.奥哈拉伦 David R.O'Hallaron 卡内基-梅隆大学电子和计算机工程系教授。 在弗吉尼亚大学获得计算机科学的博士学位,2007 年一2010年为Intel匹兹堡实验室主任。他教授本科 生和研究生的计算机系统方面的课程已有20余年, 并和Bryanta教授一起开设了“计算机系统导论”课 程。曾获得CMU计算机学院颁发的Herbert Simon杰 出教学奖。他主要从事计算机系统领域的研究,与 Quake:项目成员一起获得过高性能计算领域中的最高 国际奖项Gordon Bell奖。他目前的工作重点是 研究自动分级(autograding)概念,即评价其他程 序质量的程序
书(简称CS:APP)的主要读者是计算机科学家、计算机工程师,以及 那些想通过学习计算机系统的内在运作而能够写出更好程序的人。 我们的目的是解释所有计算机系统的本质概念,并向你展示这些概 念是如何实实在在地影响应用程序的正确性、性能和实用性的。其他的 系统类书籍都是从构建者的角度来写的,讲述如何实现硬件或系统软件, 包括操作系统、编译器和网络接口。而本书是从程序员的角度来写的, 讲述应用程序员如何能够利用系统知识来编写出更好的程序。当然,学 习一个计算机系统应该做些什么,是学习如何构建一个计算机系统的很 好的出发点,所以,对于希望继续学习系统软硬件实现的人来说,本书 也是一本很有价值的介绍性读物。大多数系统书籍还倾向于重点关注系 统的某一个方面,比如:硬件架构、操作系统、编译器或者网络。本书 前 则以程序员的视角统一覆盖了上述所有方面的内容。 如果你研究和领会了这本书里的概念,你将开始成为极少数的“牛 言 人”,这些“牛人”知道事情是如何运作的,也知道当事情出现故障时如 何修复。你写的程序将能够更好地利用操作系统和系统软件提供的功能, 对各种操作条件和运行时参数都能正确操作,运行起来更快,并能避免出 现使程序容易受到网络攻击的缺陷。同时,你也要做好更深人探究的准备, 研究像编译器、计算机体系结构、操作系统、嵌人式系统、网络互联和网络 安全这样的高级题目。 读者应具备的背景知识 本书的重点是执行x8664机器代码的系统。对英特尔及其竞争对手而 言,x86-64是他们自1978年起,以8086微处理器为代表,不断进化的最新 成果。按照英特尔微处理器产品线的命名规则,这类微处理器俗称为“x86”。 随着半导体技术的演进,单芯片上集成了更多的晶体管,这些处理器的计算 能力和内存容量有了很大的增长。在这个过程中,它们从处理16位字,发展 到引入IA32处理器处理32位字,再到最近的x8664处理64位字。 我们考虑的是这些机器如何在Liux操作系统上运行C语言程序。 Linux是众多继承自最初由贝尔实验室开发的Unix的操作系统中的一种。 这类操作系统的其他成员包括Solaris、FreeBSD和MacOS X。近年来
XII 由于Posix和标准Ux规范的标准化努力,这些操作系统保持了高度兼容性。因此,本书内 容几乎直接适用于这些“类Unix”操作系统。 文中包含大量已在Liux系统上编译和运行过的程序示例。我们假设你能访问一台这样的 机器,并且能够登录,做一些诸如切换目录之类的简单操作。如果你的计算机运行的是M crosoft Windows系统,我们建议你选择安装一个虚拟机环境(例如VirtualBox或者VMWare), 以便为一种操作系统(客户(OS)编写的程序能在另一种系统(宿主OS)上运行。 我们还假设你对C和C++有一定的了解。如果你以前只有Java经验,那么你需要付出更 多的努力来完成这种转换,不过我们也会帮助你。Java和C有相似的语法和控制语句。不过, 有一些C语言的特性(特别是指针、显式的动态内存分配和格式化I/O)在Java中都是没有的。 所幸的是,C是一个较小的语言,在Brian Kernighan和Dennis Ritchie经典的“K&R”文献中 得到了清晰优美的描述[61]。无论你的编程背景如何,都应该考虑将K&R作为个人系统藏书 的一部分。如果你只有使用解释性语言的经验,如Python、Ruby或Perl,那么在使用本书之 前,需要花费一些时间来学习C。 本书的前几章揭示了C语言程序和它们相对应的机器语言程序之间的交互作用。机器语言 示例都是用运行在x86-64处理器上的GNU GCC编译器生成的。我们不需要你以前有任何硬 件、机器语言或是汇编语言编程的经验。 给C语言初学者关于0编程语言的建议 为了帮助C语言编程背景薄弱(或全无背景)的读者,我们在书中加入了这样一些专门的 注释来突出C中一些特别重要的特性。我们假设你熟悉C++或Java。 如何阅读此书 从程序员的角度学习计算机系统是如何工作的会非常有趣,主要是因为你可以主动地做这 件事情。无论何时你学到一些新的东西,都可以马上试验并且直接看到运行结果。事实上,我 们相信学习系统的唯一方法就是做(do)系统,即在真正的系统上解决具体的问题,或是编写和 运行程序。 这个主题观念贯穿全书。当引人一个新概念时,将会有一个或多个练习题紧随其后,你应 该马上做一做来检验你的理解。这些练习题的解答在每章的末尾。当你阅读时,尝试自己来解 答每个问题,然后再查阅答案,看自己的答案是否正确。除第1章外,每章后面都有难度不同 的家庭作业。对每个家庭作业题,我们标注了难度级别: ·只需要几分钟。几乎或完全不需要编程
XIII ·可能需要将近20分钟。通常包括编写和测试一些代码。(许多都源自我们在考试中出 的题目。) 幸需要很大的努力,也许是1一2个小时。一般包括编写和测试大量的代码。 :一个实验作业,需要将近10个小时。 文中每段代码示例都是由经过GCC编译的C程序直接生成并在Liux系统上进行了测试, 没有任何人为的改动。当然,你的系统上GCC的版本可能不同,或者根本就是另外一种编译 器,那么可能生成不一样的机器代码,但是整体行为表现应该是一样的。所有的源程序代码都 可以从csapp.cs.cmu.edu上的CS:APP主页上获取。在本书中,源程序的文件名列在两条水平线的 右边,水平线之间是格式化的代码。比如,图1中的程序能在code/intro/目录下的hello.c文件中找 到。当遇到这些示例程序时,我们鼓励你在自己的系统上试着运行它们。 code/intro/hello.c 1 #include <stdio.h> 2 int main() 4 printf("hello,world\n"); 6 return 0; code/intro/hello.c 图1一个典型的代码示例 为了避免本书体积过大、内容过多,我们添加了许多网络旁注(Web aside),包括一些对 本书主要内容的补充资料。本书中用CHAP:TOP这样的标记形式来引用这些旁注,这里 CHAP是该章主题的缩写编码,而T(OP是涉及的话题的缩写编码。例如,网络旁注DATA: BOOL包含对第2章中数据表示里面有关布尔代数内容的补充资料:而网络旁注ARCH: VLOG包含的是用Verilog硬件描述语言进行处理器设计的资料,是对第4章中处理器设计部 分的补充。所有的网络旁注都可以从CS:APP的主页上获取。 旁注什么是旁注 在整本书中,你将会通到很多以这种形式出现的旁注。旁注是附加说明,能使你对当前 讨论的主题多一些了解。旁注可以有很多用处。一些是小的历史故事。例如,C语言、 Linux和Internet是从何而来的?有些旁注则是用来澄清学生们经常感到疑惑的问题。例如, 高速缓存的行、组和块有什么区别?还有些旁注给出了一些现实世界的例子。例如,一个浮 点错误怎么毁掉了法国的一枚火箭,或是给出市面上出售的一个磁盘驱动器的几何和运行参 数。最后,还有一些旁注仅仅就是一些有趣的内容,例如,什么是“hoinky'”?