`.
兰镶尔 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余年, 井和Bryant 教授一起开设了 ”计算机系统导论 ” 课程。曾获得CMU计算机学院颁发的Herbert Simon杰出教学奖。他主要从事计算机系统领域的研究 , 与
Quake项目成员一起获得过高性能计算领域中的最高 国际奖项—-G ordon Bell奖。他目前的工作重点是研究自动分级 ( autograding ) 概念, 即评价其他程序质量的程序。
“山匾
••••••• ·-
深人理解计算机系统
兰德尔 E. 布莱恩特 ( Randal E. Bryant)
[美] 卡内基-梅隆大学 著
大卫 R. 奥哈拉伦 ( David R. O’Hallaron)
卡内基-梅隆大学
龚奕利贺莲译 #
Computer Systems
A Program1ner’s Perspective Third Edition
@机械工业出版社 #
China Machine P「ess
图 书在版编目 ( CIP ) 数 据 #
深入理 解计算 机系统(原书第 3 版)/(美)兰德尔. E. 布莱恩特 ( Ra n d a l E. Br y a n t ) 等著; 龚奕 利 ,贺 莲 译 .— 北京 :机械工业出 版社 , 2 0 1 6 .7
(计算机科学丛书)
书名原文: Computer Systems: A Programmer’s Perspective, Third Edition ISBN 978-7-111-54493-7
深… IL CD兰… (2)龚.. ® 贺… III. 计笢机系统 IV. TP338
中国版本图书馆CIP数据核字 ( 20 1 6 ) 第 1 8 23 6 7 号
本书版权登记号:图字: 01-2015 -2044
Authorized translation from the English language edition, entitled Computer Systems: A Programmer’s Perspective, 3E, 9780134092669 by Randal E. Bryant, David R. O’Hallaron, published by Pearson Education, Inc., Copyright©2016, 2011, and 2003
All rights reserved. No part of this book may be reproduced or transmit ted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc.
Chinese simplified language edition published by Pearson Educ a t io n Asia Ltd., and China Machine Press Copyr ight © 2016.
本书中文 简体字版由 Pe arson Education (培生教育出版集团)授权机械工业出版社在中华入民共和国境内(不包括中国台湾地区和中国香港、澳门特别行政区)独家出版发行。未经出版者书面许可, 不得以任何方式抄袭、复制或节录本书中的任何部分。
本书封底贴有 Pe ars on Education (培生教育出版集团)激光防伪标签,无标签者不得销售。
本书从程序员的视角详细阐述计算机系统的 本质概念,并 展 示这些概 念如何 实实 在在 地影响应用程序的正确性、性能和实用性。全书共 12 章,主要包括信息的 表示和处 理 、程 序的 机器级表示、处理 器体 系结 构 、优化 程序性能 、存储器层次结构 、链接 、异常控制流 、虚拟存储 器 、系统 级 1/0 、网 络编程、并发编程等内容。书中提供了大量的例子和练习题,并给出部分答案,有助于读者加深对正文所述
概念和知识的理解。
本书适合作为高等院校计算机及相关专业本科生、研究生的教材,也可供想要写出更快、更可靠程序的程序员及专业技术入员参考。
出版发行 :机械工 业出版社 (北京市西城区百万庄大街22 号 邮政编码: 100037)
责任编辑:和静
印 刷:中国电影出版社印刷厂
开本: 185mm x 260mm 1/16
书号: ISBN 978-7-111-54493-7
责任校对:殷 虹
版 次 : 2016 年 11 月 第 1 版 第 1 次 印 刷
印张: 48.25
定价: 139.00 元
凡购本书,如有缺页、倒页 、脱页, 由本社发行部调换
客服热线: (010) 88378991 88361066 投稿热线: ( 010 ) 88 379604
购书热线: (010) 68326294 88379649 68995259 读者信箱: hzjs j@ hzbook.com
版权所有·侵权必究
封底无防伪标均为盗版
本书志律顾问: 北京大成律师 事务所 韩光/邹晓东
文 : 复兴以来,源 远流长的科学精神和逐 步形成的学术规范, 使西国家在自然科学的各个领域取得了垄断性的优势;也正是这样
的优势, 使美国 在信息技术发展的六十多年间名家辈出、独领风骚。在商业化的进程中,美国的产业界与教育界越来越紧密地结合,计算机学 科中的许多泰山北斗同时身处科研和教学的最前线,由此而产生的经典 科学著作,不仅擘划了研究的范畴,还揭示了学术的源变,既遵循学术 规范, 又自有 学者个性, 其价值并不会因年月的 流逝而减退。
近年,在全球信息化大潮的推动下,我国的计算机产业发展迅猛, 对专业人才的需求日益迫切。这对计算机教育界和出版界都既是机遇, 也是挑战;而专业教材的建设在教育战略上显得举足轻重。在我匡信息 技术发展时间较短的现状下,美国等发达国家在其计算机科学发展的几 十年间 积淀和发展的经典教材仍有许多值得借鉴之处。因此,引进一批国外优秀计算机教材将对我国计算机教育事业的发展起到积极的推动作 用,也 是 与世界接轨、建设真正的世界一流大学的必由之路。
机械工业出版社华章公司较早意识到“出版要为教育服务”。 自 1998 年开始 ,我 们就将工作重点放在了遴选、移译国外优秀教 材上。经过多年的 不 懈 努 力, 我 们 与 P earson , McGraw-Hill, Elsevier, MIT, John Wiley & Sons, Cengage等世界著名出版公司建立了良好的合作关系, 从他们现 有的数百 种教 材中甄选出 Andrew S. T anenb aum , Bjarne Strous trup, Brian W. Kernighan, Dennis Ritchie, Jim Gray, Afred V. Aho , John E
. Hopcroft, Jeffrey D. Ullman, Abraham Silberschatz, William Stallings, Donald E. Knuth, John L. Henness y , Larry L. Peterson 等大师名家的一批经典作品,以“计算机科学丛书”为总称出版,供读者学习、研究及 珍藏。大理石纹理的封面,也 正体现了这套丛书的品位和格调 。
”计 算机科学丛书” 的 出版工作得到了国内外学者的鼎力相助, 国内的专家不仅提供了中 肯的选题指导, 还不辞劳苦地担 任了 翻译 和审校的工作; 而原书的作者也相当关注其作品在中国的传播,有的还专门为其书的中译本 作序。迄今,”计算机科学丛书”已经出版了近两百个品种,这些书籍在读 者中树立了良好的口碑 ,并被许多 高校采用为正式教材和参考书籍。其影印版“经典原版书库”作 为姊妹篇也被越来越多实施 双语教学的学校所采用。
IV #
权威的作者、经典的教材、一流的译者、严格的审校、精细的编辑,这些因素使我们的图 书有了质量的保证。随着计算机科学与技 术专业学科建设的不断完善和教材改革的逐渐深化, 教育界对国外计算机教材的需求和应用都将步入一个新的阶段,我们的目标是尽善尽美,而反 馈的意见正是我们达到这一终极目标的重要帮助。华章公司欢迎老师和读者对我们的工作提出
建议或给予指正, 我们的联系方法如下:
华章网站: www. hzbook. com 电子邮件: hzjsj@ hzbook. com 联系电话: (010)88379604
联系地 址: 北京 市西城 区百 万庄 南街 1 号
邮政编码: 100037
==吾
ITrf:1'1ffl #
华章教育
华章科技图书出版中心
4 匕 章 公 司 温 莉 芳 女 士 邀 我 为 即 将 出 版 的《Computer Systems: A
- – rramgmer ’s Pers pective》第3 版的中文译本《深入理解计算机系
统》写个序, 出于两方面的考虑,欣 然允 之。
一是源于我个人的背景和兴趣。我长期从事软件工程和系统软件领域的研究,对计算机学科的认识可概括为两大方面:计算系统的构建和基于计算系统的计算技术应用。出于信息时代国家掌握关键核心技术的重大需求以及我个人专业的本位视角,我一直对系统级技术的研发给予更多关注,由于这种“偏爱”和研究习惯的养成,以至于自己在面对非本
专业领域问题时,也常常喜欢从“系统观”来看待问题和解决问题。我自 己也 和《深入理解计 算机系统》有过“亲密接触”。2012 年, 我还在北京大学信息科学技术学院院长任上,学院从更好地培养适应新技术、发展具 有系统设计和系统应用能力的计算机专门人才出发,在调查若干国外高 校计算机学科本科生教学体系基础上,决定加强计算机系统能力培养, 在本科生二年级增设了一门系统级课程,即“计算机系统导论”。其时, 学校正 在倡导小班课教学模式,这 门 课 也 被选为学院的第一个小班课教学试点。为了体现学院的重视, 我亲自担任了这门课的主持人, 带领一个 18 人组成的"豪华“教学团队负责该课程的教学工作, 将学生分成 14 个小班, 每个小班不超过 15 人。同时,该 课 程涉及教师集体备课组合授课、大班授课基础上的小班课教学和讨论、定期教学会议、学生自主习 题课和实验课等新教学模式的探索,其中一项非常重要的举措就是选用 了卡内 基-梅隆大学 Randal E. Brya nt 教授和 David R. O ’ H allaron 教授编写的《Computer Systems: A Programmer’s Pers pective》(第 2 版)作为教材。虽然这门课程我只主持了一次, 但对这本教材的印象颇深颇佳。
发中中 #
展国 #
中科文
家国院学版科院
言士序_
士院
、一
梅
本…….
二是源于我 和华章公司已有的良好合作和相互了解。2000 年前 后 , 我先后翻译了华章公司引进(机械工业出版社出版)的Roger P ress man 编写的《Sof tware Engineering: A P ra ctitio ner ’ s App roach》一书的第 4 版和第
5 版。其后, 在计算机学会软件工程专业委员 会和系统 软件专业委员 会的诸多学术活动中也和华章公司及温莉芳女士本人有不少合作。近二十年来,华章公司的编辑们引进出版了大量计算机学科的优秀教材和学术著作,对国内高校计算机学科的教学改革起到了积极的促进作用,本书的
VI
翻译出版仍是这项工作的延续。这是一项值得褒扬的工作,我也想借此机会代表计算机界同仁 表达对华章公司的感谢!
计算机系统类别的课程一直是计算机科学与技术专业的主要教学内容之一。由于历史原 因, 我国的计算机专业的课程体系曾广泛参考 ACM 和 IEEE 制订的计算机科学与技术专业教学计划( Computing C urricula ) 设计,计 算机系统类课程也参照该计划分为汇编语言、操作系统、组成原理、体系结构、计算机网络等多门课程。应该说,该课程体系在历史上对我国的计算机 专业教育起了很好的引导作用。
进入新世纪以来,计算技术发生了重要的发展和变化,我国的信息技术和产业也得到了迅 猛发展, 对计算 机专业的毕业生提出了更高要求。重新审视原来我们参照 ACM/ IEEE 计算机专业计划的课程体系,会发现存在以下几个方面的主要问题。
) 课程体系中缺乏 一门独立的能够贯穿整个计算机系统 的基础课程。计算机系统 方面的基础知识被分 成了很多门独立的课程, 课程内容彼此之间缺乏关联和系统性。学生学习之后; 虽然在计算机系统的各个部分理解了很多概念和方法,但往往会忽视各个部分之间的关联,难 以系统性地理解整个计算机系统的工作原理和方法。
) 现有课程往往偏重理论, 和实践关联较少。如现有的系统课程中通常会介绍函数调用过程中的压栈和退栈方式,但较少和实践关联来理解压栈和退栈过程的主要作用。实际上,压 栈和退栈与理解 C 等高级语言的丁作原理息息相关,也 是常用的攻击手段 Buffer Overflow 的主要技术基础。
- 教学内容比较传统 和陈旧, 基本上是早期 PC 时代的内容。比如, 现在的主流台式机CPU 都巳经是 x86-64 指令集, 但较多课程还在教授 80386 甚至更早的指令集。 对于近年 来出现的多核/众核处理器、SSD 硬盘等实际应用中遇到的内容更是涉及较少。
4 ) 课程大多数从设计者的 角度出发, 而不是从使用者的角度出发。对于大多数学生来说, 毕 业之后并不会成为专业的 CP U 设计人员、操作系统 开发人员等, 而是会成为软件开发工程师。对他们而言,最重要的是理解主流计算机系统的整体设计以及这些设计因素对于应用软件 开发和运行 的影响。
这本教材很好地克服了上述传统课程的不足,这也是当初北大计算机学科本科生教学改革 时选择该教材的主要考量。其一,该 教材系统地介绍了整个计算 机系统的工作原理, 可帮助学生系统性地理解计算机如何执行程序、存储信息和通信;其 二 ,该 教材非常强调实践, 全书包括 9 个配套 的实验, 在这些实验中,学 生需要攻破计算机系统、设计 CPU、实现命令行解 释器、根据缓存优化程序等 , 在新 鲜有趣的实验中理解系统原理, 培养动手能力; 其三,该 教材紧跟时代的发展, 加入了 x86- 64 指令集、Intel Core i7 的虚拟地址结构、SSD 磁盘、IPv6 等新技术内 容:其 四 .该 教材从程序员 的角度看待计算机系统, 重点讨论系统的不同结构对于上层
VII
应用软件编写、执行和数据存储的影响,以培养程序员在更广阔空间应用计算机系统知识的 能力。
基千该教材的北大”计 算机系统导论”课程实施已有五年, 得到了学生的广泛赞誉, 学生们通过这门课程的学习建立了完整的计算机系统的知识体系和整体知识框架,养成了良好的编程 习惯并获得了编写高性能、可移植和健壮的程序的能力,奠定了后续学习操作系统、编译、计 算机体系结构等专业课程的 基础。北大的教学实践表明 , 这是一本值得推荐采用的好教材。
该书的第 3 版相对千第 2 版进行了较大程度的修改和扩充。第 3 版从一开始就采用最新x86-64 架构来贯穿各部分知识, 在内存技术、网络技术上也有一系列 更新,并 且重组了之前的一些比较难懂的内容。我相信,该 书的出版, 将有助千国 内计算机系统教学的进一步改进, 为
培养从事系统级创新的计算机人才奠定很好的基础。
琴 归
2016 年 10 月 8 日
2 00 2 年 8 月本书第 1 版首 次印刷。一个月之后, 我在复旦大学软件学院开设 了”计 算机系统 基础”课 程, 成为国 内 第一个采用这本教材授
课的老师。这本教材有四个特点。第一, 涉及面广, 覆盖了二进制、汇编、组成、体系结构、操作系统、网络与并发程序设计等计算机系统最 重要的方面。第二, 具有相当的深度, 本书从程序出发逐步深入到系统领域的重要问题,而非点到为止,学完本书后读者可以很好地理解计算 机系统的工作原理。第三,它 是 面向 低年级学生的教材, 在过去的教学体系中这本书所涉及的很多内容只能在高年级讲授,而本书通过合理的 安排将计算机系统领域最核心的内容巧妙地展现给学生(例如,不需要掌 握逻辑设计与硬件描述语言的完整知识,就可以体验处理器设计)。第 四, 本书配备了非常实用、有趣的实验。例如, 模仿硬件仅用位操作完成复杂的运算 , 模仿 t racker 和 hacker 去破解密码以及攻击自身的程序, 设 计 处理器, 实现简单但功能强大的 Shel l 和 P ro xy 等。这些实验既强化了学 生对书本知识的理解,也 进一步激发了学生探究计算机系统的热情。
以低年级开设“深入理解计算机系统”课程为基础,我先后在复旦大 学和上海交 通大学软件学院主导了激进的教学改革。必修课时被大量压缩,现在软件工程专业必修课由问题求解、计算机系统基础、应用开发 基础、软件工程四个模块 9 门 课 构成。其他传统的必修课如操作系统、编译原理、数字逻辑等都成为方向课。课程体系的变化,减少了学生修 读课程的总数和总课时,因而为大幅度增加实验总最、提高实验难度和 强度、增强实验的综合性和创新性提供了有力保障。现在我的课题组的 青年教师全部是首批经历此项教学改革的学生。本科的扎实基础为他们 从事系统软件研究打下了良好基础,他们实现了亚洲学术界在操作系统 旗舰会议 SOS P 上论文发表零的突破,目 前 研 究 成果在国际上具有较大 的影响力。师资力批的补充, 又为全面推进更加激进的教学改革创造了条件。
本书的出版标志着国际上计算机教学进入了第三阶段。从历史来看, 国 际 上计算机教学先后经历了三个主要阶段。第一阶段是上世纪 70 年代中期至 80 年代中期.那时理论、技术还不成熟, 系统不稳定,因 此教材主要阶绕若干重要问题讲授不同流派的观点,学生解决实际问题的能力
IX #
不强。第二阶段是上世纪 80 年代中期至本世纪初, 当时计算机单机系统的理论 和技术已逐步趋于成熟,主流系统稳定,因此教材主要围绕主流系统讲解理论和技术,学生的理论基础扎 实, 动手能力强。第三阶段从 本世纪初开始, 主要 背景是随着互 联网的兴起,信 息 技术开始渗透到人类工作和生活的方方面面。技术爆炸迫使教学者必须重构传统的以计算机单机系统为主 导的课程体系。新 的体系大面积调 整了 核心课程的内容。核心课程承担了帮助学生构建专业知识框架的任务, 为学生在毕业后相当长时间内的专业发展奠定坚实基础。现在一般认为问 题抽象、系统抽象和数据抽象是计算机类专业毕业生的核心能力。而本书担负起了系统 抽象的重任, 因此美国的很多高校都采用了该书作为计算机系统核心课程的教材。第三阶段的教材与第二阶段的教材是互补关系。 第三阶段的教材主要强调坚实而宽 广的基础, 第二阶段的教材主要强调深入系统的专门知识,因此依然在本科高年级方向课和研究生专业课中占据重要地位。
上世纪 80 年代初, 我国借鉴美国经验建立了自己的计算机教学体系并引进了大最教材。从 21 世纪初开 始, 一些学校开始借鉴美国第二阶段的教学方法, 采用了部分第二阶段的著名教材, 这些改革正在走向成熟并得以推广。2012 年北京大学计算机专业采用本书作为教材后, 采用本教材开设“计算机系统 基础”课程的高校快速增 加。以此为契机, 国内的计算机教学也有望全面进入第三阶段。
本书的第 3 版完全按照 x86- 64 系统进行改写。此外, 第 2 版中删除了以 x87 呈现的浮点指令, 在第 3 版中浮点指令又以标量 AVX2 的形式得以恢复。第 3 版更加强调并发, 增加了较大篇幅用于讨论信号处理程序与主程序间并发时的正确性保障。总体而言, 本书的三个版本在结构上没有太大变化,不同版本的出现主要是为了在细节上能够更好地反映技术的最新变化。
当然本书的某些部分对于初学者而言还是有些难以阅读。本书涉及大蜇重要概念, 但一些概念首 次亮相时并没有编排好顺序。例如寄存器的概念、汇编指令的顺序执行模式、PC 的概念等对 千初学 者而言非常陌生, 但这些 介绍仅仅出现在第 1 章的总览中, 而当第 3 章介绍汇编时完全没有进一步的展开就 假设读者已经非常清楚这些概念。事实上这些概念原本就介绍得过 千简单,短暂亮相之后又立即退场,相隔较长时间后,当这些概念再次登场时,初学者早已忘 却了它们是什么。同样,第 8 章对进程、并发等概念的介绍也存在类似问 题。因此, 中文翻译版将 配备导读部分, 希望这些导读能够帮助初学者顺利阅读。
2016 年 10 月 15 日
书第 1 版出版于 2003 年, 第 2 版出版于 2011 年,去 年发行的巳经是原书第 3 版了。第 3 版还是采用以下组合方式: 在经典的
x86 架构机器上运行 Linux 操作系统 ,采用 C 语言编程。这样的 组合经受住了时间的考验。这一版的一个明显变化就是从讲解 I A32 和 x86-64 转变为完全以 x86-64 为基础, 相应地修改了第 3、4 、5 、6 和 7 章。同时, 还改写了第 2 章 , 使之更易读、好懂;用 近期的 新技术更新了第 6 、11 和12 章。这些变化 使得本书既 和新技术保持了同步, 又保留了描述系统本质的内容以及从程序员角度出发的 特色。
除了翻译本书,我们也开始以本书为教材讲授”计算机系统基础”课 程, 对这本书的理解也随之越来越深入, 意 识 到除了阅读之外, 动手实践更是学习计算机系统的 必经之路。本书的官 网提供了很多实 验作业(Lab Assignment), 其中不乏有趣且有一定难度的 实验, 比如 Bomb Lab 。有兴趣的读者除了阅读本书的内容之外,还应该试着去完成这些实验, 让纸面上的内容在实际动手中得到巩固和加强。本书的官方博客也不断 更新着有关这本书和配套课程的最新变化, 这也是对本书的有益补充 。
第 3 版从翻译 的角度来说, 我 们尽量做到更流畅, 更符合中文表达的习惯。对于一些术语, 比如 memo ry , 以前怕出错就统一翻译 成存储器, 现在则尽可能 地按照语境去区分, 翻译 成内存或者存储器。
在此 , 要感谢本书的编辑朱劼、姚蕾以及和静, 有她们的支持、鼓励和耐心 细致的工作,才能 让本书如期与读者见面。
由于本书内 容多, 翻译 时间紧迫,尽 管 我们尽量做到认真仔细, 但还是难以避免出现错误和不尽如人意的地方。在此欢迎广大读者批评指 正。我们也会一如既往地维护勘误表, 及时在网上更新,方 便 大家阅读。
(另外, 本版第 1 次印刷时, 我们已经根据官网 2016 年 3 月 1 日前 发布的勘误进行了修正, 就不在中文勘误中再翻译 了。)
龚奕利 贺莲
201 6 年 5 月 于硌 珈 山
本 书(简称C,S APP) 的主要读者是计算机科学 家、计算机工程 师,以 及那些想通过学习计算机系统的内在运作而能够写出更好程序的人。
我们的目的是解释所有计算机系统的本质概念,并向你展示这些概念是如何实实在在地影响应用程序的正确性、性能和实用性的。其他的系统类书籍都是从构建者的角度来写的,讲述如何实现硬件或系统软件, 包括操作系统 、编译器和网络接口。而本书是从程序 员 的 角 度来写的, 讲述应用程序员如何能够利用系统知识来编写出更好的程序。当然,学习一个计算机系统应该做些什么,是学习如何构建一个计算机系统的很好的出发点,所以,对于希望继续学习系统软硬件实现的人来说,本书也是一本很有价值的介绍性读物。大多数系统书籍还倾向于重点关注系统的某一个方面,比如:硬件架构、操作系统、编译器或者网络。本书则以程序员的视角统一覆盖了上述所有方面的内 容。
如果你研究和领会了这本书里的概念,你将开始成为极少数的“牛 人",这些“牛人“知道事情是如何运作的,也知道当事情出现故障时如 何修复 。你写的程序将能够更好地利用操作系统 和系统 软件提供的功能, 对各种操作条件和运行时参数都能正确操作,运行起来更快,并能避免出 现使程序容易受到网络攻击的缺陷。同时,你也要做好更深入探究的准备, 研究像编译器、计算机体系结构、操作系统、嵌入式系统、网络互联和网络安全这样的高级题目。
读者应具备的背景知识 #
本书的重点是执行 x86-64 机器代码的系统。对英特尔及其竞争对手而言, x86-64 是他们自 1978 年起 ,以 8086 微处理器为代 表,不 断 进化的最新成果。按照英特尔微处理器产品线的命名规则, 这类微处理器俗称为 " x86"。随着半导体技术的演进,单芯片上集成了更多的晶体管,这些处理器的计算 能力和内存容量有了很大的增长。在这个过程中 ,它 们从处理16 位字, 发展到引入 IA32 处理器处理 32 位字,再 到最近的 x86-64处理 64 位字。
我们考虑的是这些机器如何在 Linux 操作系统上运行 C 语言程序。
Linux 是众多继承自最 初由贝尔实验室开发的 U nix 的 操 作 系统中的一种。这类操作系统的其他成员 包括 Solaris 、 Fr eeBSD 和 MacOS X。 近年 来,
XII #
由 千 Pos ix 和标 准 U nix 规范的标准化努力, 这些操作系统 保持了高度兼容性。因此, 本书内容几乎直接适用千这些 “类 U nix" 操作系统。
文中 包含大横已在 Linux 系统上编译和运行过的程序示例。我们假设你能访问一台这样的机器,并 且 能 够登录, 做一些诸如切换目录之类的简单操作。如果你的计算机运行的是 Mi crosoft Windows 系统 , 我们建议你选择安装一个虚拟机环境(例如 Virt ua!Box 或者 VMWa re ) , 以便为一 种操作系统(客户 OS) 编写的程序能在另一种系统(宿主 OS) 上运行。
我们还假设你对 C 和 C+ + 有一定的了解。如果你以前只有 Java 经验, 那么你需要付出更多的努力来完成这种 转换, 不过我 们也会帮助你。Java 和 C 有相似的语法和控制语句。不过, 有一些 C 语言的特性(特别是指针、显式的动态内 存分配和格式化 1/ 0 ) 在 Java 中都是没有的。所幸的是,C 是一个较小的语言, 在 Brian Kern ig han 和 Dennis Ritch ie 经典的 " K& R" 文献中得到了清晰优美的描述[ 61] 。无论你的编程背景如何, 都应该考虑将 K & R 作为个人系统 藏书的一部分。如果你只有使用解 释性语言的经验, 如Python 、R uby 或 Perl , 那么在使用本书之前,需 要 花 费 一些时间来学习 C。
本书的前几章揭示了 C 语言程序和它们相对应的机器语言程序之间的交互作用。 机器语 言示例都是用运行在 x86-64 处理器上的 G NU GCC 编译器生成的。我们不需要你以前有任何硬件、机器语言或是汇编语言编程的经验。
区 关千 C 编程语言的建议
为 了帮 助 C 语言编程背景 薄弱(或全无背景)的读者, 我们在书 中加入了这 样一些专 门的注释 未突出 C 中一些特 别重要的特性。我们假设你熟悉 C+ + 或 Java 。
如何阅读此书
从程序员的角度学习计算机系统是如何工作的会非常有趣,主要是因为你可以主动地做这 件事情。无论何时你学到一些新的东西, 都可以 马上试验并且直接看到运行结果。事实上, 我们相信学习系统的唯一方法就 是做C do ) 系统 ,即 在真正的系统上解决具体的问题, 或是编写 和运行程序。
这个主题观念贯穿全书。当引入一个新概念时,将会有一个或多个练习题紧随其后,你应 该马上做一做来检验你的理解。这些练习题的解答在每章的末尾。当你阅读时,尝试自己来解 答每个问 题, 然后 再查阅答案, 看自己的答案是否正确。除第 1 章外, 每章 后面都有难度不同的 家庭作业。对每个家庭作业题, 我们标注了难度级别:
- 只 需 要几分钟。几乎或完全不需要编程。
XIII #
•• 可能需要将近 20 分钟。通常包括编写和测试一些代码。(许多都源自我们在考试中出的题目。)
***需 要很大的努力 ,也 许 是 1 ~ 2 个 小 时。一般包括编写和测试大量的代码。
::- 个实验作业, 需 要 将近 1 0 个小时。
文中 每段代码示例都是由经过 GCC 编译的 C 程序直接生成并在 Linux 系统 上进行了测试, 没有任何人为的改动。当然, 你的系统上 GCC 的版本可能不同, 或者根本就是另外一种编译器, 那么可能生成不一样的机器代码, 但是整体行为表现应该是一样的。所有的源程序代码都可以从 csapp. cs. emu. edu 上的 CS: APP 主页上获取。在本书中, 源程序的 文件名列在两条水平线的右边,水平线之间是格式化的代码。比如, 图 ]中的程序能在 code/ intro/ 目录下的 hello. c 文件中找到。当遇到这些 示例程序时 , 我们鼓励你在自己的 系统上试着运行它们 。
#include <stdio.h> int main()
{
printf(“hello, world\n”); return O;
}
code/intro/hello.c
code/intro/hello.c
图 1 一个典型的代码示例
为了 避免本书体积过大、内容过多, 我们添加了许多网络旁注( Web a邓ide ) , 包括一些对本书主要内 容的 补充资料。本书中用 C H AP : T O P 这样的标记形式来引 用 这 些 旁注, 这里CH AP 是该章主题的缩写编码, 而 T O P 是涉及的话题的缩写编码。例如,网 络旁注 DAT A : BOOL 包含对第 2 章中数据表示里面有关布尔 代数内容的补充资 料; 而 网络旁 注 ARC H : V LOG 包含的是用 Verilog 硬件描述语言进行处理器设计的资料, 是对第 4 章 中处理器设计部分的补充。所有的网络旁注都 可以从 CS : AP P 的主页上获取。
m 什么是旁注
在整本书中,你将会遇到很多以这种形式出现的旁注。旁注是附加说明,能使你对当前 讨论的主题多一些了解。旁注可以有很多用处。 一 些是 小的 历 史故 事。 例如, C 语 言 、
Linux 和 Int ernet 是从何而 来的? 有些旁注则是 用 来澄 清学 生们 经常感到疑惑的 问题。例如,
高速缓存的行、组和块有什 么区 别? 还有些旁注给 出 了一 些现 实世 界 的例 子。 例如 , 一 个浮点错误怎么毁掉了法国的一枚火箭,或是给出市面上出售的一个磁盘驱动器的几何和运行参 数。最后, 还有一些旁注仅 仅就是一些有趣 的内容,例 如 , 什 么是 " hoink y" ?
XIV
本书概述
本书由 12 章组成, 旨在阐述计算机系统的核心概念。内容概述如下:
笫 1 章: 计算机 系统漫并。这一章通过研究 " hello , world" 这个简单程序的生命周期, 介绍计算机系统的主要概念和主题。
笫 2 章: 信 息的表示和 处理。我们讲述了计算机的算术运算, 重点描述了会对程序员有影响的无符号数和数的补码表示的特性。我们考虑数字是如何表示的, 以及由此确定对于一个给定的字长, 其可能 编码值的范围。我们探讨有符号和无符号数字之间类型转换的效果,还 阐述算术运算的数 学特性。菜鸟级程序员经常很惊奇地了解 到(用补码表示的) 两个正数的和或者 积可能 为负。另一方面,补 码的算术运算满足很 多整数运算 的代数特性,因 此 , 编译器可以很安全地把一个常量乘法转化为一 系列的移位和加法。我们用 C 语言的位级操作来说明布尔代 数的原理和应用。我们从两个方 面讲述了 IEEE 标准的浮点格式:一 是 如何用它来表示数值,一是 浮点运算的数学属性。
对计算机的算术运算 有深刻的理解是写出可靠程序的关键。比如, 程序员 和编译器不能用表达式( x- y<O ) 来 替 代( x <y) ’ 因为前者 可能会产生溢出。甚至也不能用表达式( - y<- x ) 来替 代, 因为在补码表示中负数和正 数的范围是不对称的。算术溢出是 造成 程序错误和安全漏洞的一个常见根源, 然而很少有书从程序员的角度来讲述计算机算术运算的特性。
第 3 章 : 程序的 机器级 表 示。我们教读者如何阅读由 C 编译器生成的 x86-64 机器代码。我们说明为不同控制结构(比如条件、循环和开关语句)生成的基本指令模式。我们还讲述 过程的实现,包 括栈分配、寄存器使用惯例和参数传递。我们讨论不同数据结构(如结构、联合和数组)的分配和访问方式。我们还说明实现整数和浮点 数算术运算的指令。我们还以分析程序在机器级的样子作 为途 径, 来理解常见的代码安全漏洞(例如缓 冲区溢出),以及理解程序员、编译器和操作系统可以采取的减轻这些威胁的措施。学习本章的概念能 够帮助读者成为更好的程序员, 因为你们懂得程序在机器上是如何表示的。另外一个好处就在于读者会对指针有非常 全面而具 体的理解。
第 4 章 : 处理 器体 系结 构。这一章讲述基本的组合和时序逻辑元素,并 展示这些元素如何在数据通路中组合到一起, 来执行 x86-64 指令集的一个称为 " Y86- 64" 的简化子集。我们从设 计单时钟周期数据通路 开始。这个设计概念上非常简单, 但 是 运行速度不会太快。然后我们引入流水线的思 想, 将处理一条指令所需要的不同步骤实现为独立的阶段。这个设计中,在 任何时刻, 每个阶段都 可以处理不同的指令。我们的五阶段处理器流水线更加实用。本章中处理器设计的控制逻辑是用一种称为 H CL 的简单硬件描述语言来描述的。用 HCL 写的硬件设计能够编译 和链接到本书提供的模拟器中, 还可以 根据这些设计
XV #
生成 Verilog 描述, 它适合合成到实际可以运行的硬件上去。
. 第 5 章: 优化程序性 能。在这一章里, 我们 介绍了许多提 高代 码性能的技术 , 主要思 想就是让程序员通过使编译 器能 够生成更有效的 机器代码来学习编写 C 代码。我 们一开始介绍的是减少程序需要做的工作的变换,这些是在任何机器上写任何程序时都应该遴循 的。然后讲的是增 加生成的 机器代码中指令级并行度的 变换 , 因而提 高了程序在现代
“超标量” 处理器上的性能 。为了 解释这些 变换行 之有效的 原理,我 们介绍 了一个简单的操作模型,它描述了现代乱序处理器是如何工作的,然后给出了如何根据一个程序的 图形化表示中的关键路径来测 量一个程序可能的性能 。你会惊讶 千对 C 代码做 一些简单的变换能 给程序带来多 大的速度提升 。
. 第 6 章: 存储 器层次结构 。对应用 程序员 来说 , 存储器 系统 是计算 机系统 中最直接可见的部分之一。到目前 为止 , 读者一直认同这样一 个存储 器系统 概念模型, 认为它 是一个有一致访问时间的线性数组 。实际上, 存储 器系统是一个由不同容量、造价和访问 时间的存储设备组成的层次结构 。我们讲述不同类型的随 机存取存储器 ( RAM) 和只读存储 器
CROM), 以及磁盘和固态硬盘e 的几何形状和组织构造。我们描述这些存储设备是如何放置在层 次结构中的, 讲述访问局部性是如何使这种层次结构成为可能的。我们通过一个 独特的观点使这些理论具体化, 那就是将存储器系统 视为一个“存储器山" ’ 山脊是时间局部性, 而斜坡是空间局部性。最后, 我们向读者阐述如何通过改善程序的时间局部性和空间局部性来提高应用程序的性能。
第 7 章:链 接 。本 章 讲述静态和动态链接,包 括的概念有可重定位的和可执行的目标文件、符号 解析、重定位、静态库、共享目标库、位置无关代码,以 及 库 打桩。大多数讲述系统的书中都不讲链接, 我们要讲述它是出于以下原因。第一, 程序员遇到的 最令人迷惑的问题中, 有一些和链接时的小故障有关, 尤其是对那些大型软件包来说。第二,链接器生成的目标文件是与一些像加载、虚拟内存和内存映射这 样的概念相关的。
笫 8 章 : 异常控制流。在本书的这个部分, 我们通过介绍异常控制流(即除正常分支和过程调用以外的控制流的变化)的一般概念,打 破单一程序的模型。我们给出存在于系统所有层次的异常控制流的例子, 从底层的硬件异常和中断,到 并 发进程的上下文切换,到 由 千接 收 Lin ux 信 号 引 起的控制流突变,到 C 语 言 中 破坏栈原则的非本地跳转。
在这一章, 我们介绍进程的基本概念, 进程是对一个正在执行的程序的一种抽象。读者会学习进程是如何工作的,以 及如何在应用程序中创建和操纵进程。我们
e 直译应为固态驱动器, 但固态硬盘一词已经被大家接受,所以沿 用 . 一 译 者注
XVI
会展示应用程序员如何通过 Linux 系统调用来使用多个进程。学完本章之后, 读者就能够编写带作业控制的 Linux she ll 了。同时,这 里也会向读者初步展示程序的并发执行会引起不确定的行为。
. 第 9 章: 虚拟内存 。我们讲 述虚拟内存系统是希望读者对它是如何工作的以及它的特 性有所了解。我们想让 读者了解 为什么不同的并发进程各自都有一个完全相同的地址范围,能 共享某些页, 而又独占另外一些页。我们还讲了一些管理和操纵虚拟内存的问题。特别地, 我们讨论了存储分配操作, 就像标准库的 ma l l oc 和 fr ee 操作。阐述这些内容是出于下面几个目的。它加强了这样一个概念,那就是虚拟内存空间只是一 个字节数组, 程序可以把它划分成不同的存储单元。它可以帮助读者理解当程序包含存储泄漏和非法指针引用等内存引用错误时的后果。最后,许多应用程序员编写自己 的优化了的存储分配操作来满足应用 程序的需 要和特性。这一章比其他任何一章都更能展现将计算机系统中的硬件和软件结合起来阐述的优点。而传统的计算机体系结构 和操作系统书籍都只讲述虚拟内存的某一方面。
笫 10 章 : 系统级 I/ 0 。我们讲述 Unix I/ 0 的基本概念,例 如 文件和描述符。我们描述如何共享文件, I/ 0 重定向是如何工作的, 还有如何访问文件的元数据。我们还开发了一个健壮的带缓冲区的 I/ 0 包 , 可以正确处理一种称为 short counts 的奇特行为,也 就是库函数只读取一部分的输入数据。我们阐述 C 的标准 I/ 0 库,以 及它与 Linu x I / 0 的关系, 重点谈到标准 I/ 0 的局限性, 这些局限性使之不适合网络编程。总的来说,本章的主题是后面两章 网络和并发编程的基础。
. 第 11 章 : 网络编程。对编程而言,网 络是非常有趣的 I/ 0 设备,它 将许多我们前面文中学习的概念(比如进程、信号、字节顺 序、内存映射和动态内存分配)联系在一起。网络程序还为下一章的主题 并发,提供了一个很令人信服的上下文。本章只是网 络编程的一 个很小的部分, 使读者能够编写一个简单的 Web 服务器。我们还讲述位于所有网络程序底层的 客户端-服务器模型。我们展现了一个程序员对 Internet 的观点, 并 且教 读 者如何用套接字接口来编写 Inte rnet 客户端和服务器。最后, 我们介绍超文本传输协议( HT T P) , 并开发了一个简单的迭代式 Web 服务器。
笫 1 2 章 : 并发编程。 这一章以 Internet 服务器设计为例介绍了并发编程。我们比较对照了三种编写并发程序的 基本机制(进程、I/ 0 多路复用和线程),并 且展示如何用它们来建造并发 Internet 服务器。我们 探讨了用 P 、V 信号量操作来实现同步、线程安全和可重入、竞争条件以及死锁等的基本原则。对大多数服务器应用来说,写并发 代码都是很关键的。我们还讲述了线程级编程的使用方法,用这种方法来表达应用程 序中的并行性,使 得程序在多核处理 器上能执行得更快。使用所有的核解决同一个计算问题需要很小心谨慎地协调并发线程,既要保证正确性,又要争取获得高性能。
XVII
本版新增内容
本书的第 1 版千 2003 年出版,第 2 版在 2011 年出版。考虑到计算机技术发展如此迅速, 这本书的内 容还算是保持 得很好。事实证明 Int el x86 的机器上运行 Linux( 以及相关操作系统), 加上采用 C 语言编程,是 一种能够涵盖当今许多系统的组合。然而, 硬件技术、编译器和程序库 接口的变化 ,以 及很多教师教授这些内容的经验, 都促使我们做了大量的修改。
第 2 版以 来的最大整体变化是, 我们的介绍从以 IA 32 和 x86-64 为基础, 转变为完全以 x86-64 为基础。这种重心的转移影响了很多章节的内容。下面列出一些明显的变化 :
. 第 1 章 。 我们将第 5 章对 Amdah l 定理的讨论移到了本章。
. 第 2 章 。 读者和评论家的反馈是一致的, 本章的一些内容有点令人不知所措。因此, 我们澄清了一些知识点,用 更 加 数 学 的 方 式 来描述, 使 得这些内容更容易理解。这使得读者能先略过数学细节, 获得高层次的总体概念, 然后回过头来进行更细致深入的阅读。
笫 3 章。我们将之前基千 IA32 和 x86- 64 的 表现形式转换为完全基于 x86- 64 , 还更新了近期版本 GCC 产生的代码。其结果是大量的重写工作, 包 括修改了一些概念提出的顺序。同时, 我们还首次介绍了对处理浮点数据的程序的机器级支持。由千历史原因, 我们给出了一个网络旁注描述 IA 32 机 器码。
. 第 4 章。我们将 之前基于 32 位架构的处理器设计修改为支持 64 位字和操作的设计。
.• 第 5 章。我们更新了内容以反映最近几代 x86-64 处理器的性能。通过引入更多的功能单元和更复杂的控制逻辑, 我们开发的基于程序数据流表示的程序性能模型, 其性 能 预测变得 比之前更加可靠。
第 6 章。我们对内容进行了更新,以 反映更多的近期 技术 。
第 7 章。针对 x86- 64 , 我们重写了本章, 扩充了关于用 GOT 和 P LT 创建位置无关代码的讨论, 新增了一节描述更加强大的链接技术, 比如库打桩。
. 第 8 章 。 我们增加了对信号处理程序更细致的描述, 包括异步信号安全的函数, 编写信号处理程序的具体指导原则, 以 及用 s i gs us pe nd 等待处理程序。
第 9 章 。 本章变化不大。
. 第 1 0 章。我们新增了一节说明文件和文件的 层次结构,除 此之外, 本章的 变化不大。
笫 11 章 。 我们介绍了采用最新 ge t addr i nf o 和 ge t na me i nf o 函数的、与协议无关和线程安全的网络编程, 取代过时的、不可重入的 ge t hos t b yna me 和 g e t hos t bya ddr 函数。
XVM #
笫 1 2 章。我们扩充了利用线程级并 行性使得程序在多核机器上更快运行的内容。此外,我们还增加和修改了很多练习题和家庭作业。
本书的起源
本书起源于 1998 年秋季, 我们在卡内基-梅隆 CCMU ) 大学开设的一门编号为 1 5-213的 介 绍 性课程: 计 算机系统导论 (I nt rod uction to Computer System, ICS) [ 14] 。从 那 以后 , 每学期都开设了 ICS 这门课程, 每学期有超过 400 名学生上课,这 些 学 生从本科二年级到硕士研究生都有,所学专业也很广泛。这门课程是卡内基-梅隆大学计算机科学系 (CS)以及电子和计算机工程系 CE CE) 所有本科生的必修课, 也 是 CS 和 ECE 大多数高级系统课程的先行必修课。
ICS 这门 课程的宗旨是用一种不同的方式向学生介绍计算机。因为,我 们的学生中几乎没有人有机会亲自去构造一个计算机系统。另一方面,大多数学生,甚至包括所有的计 算机科学家和计算机工程师,也需要日常使用计算机和编写计算机程序。所以我们决定从 程序员的角度来讲解系统,并采用这样的原则过滤要讲述的内容:我们只讨论那些影响用 户级 C 语言程序的性能、正确性或实用性的主题。
比如, 我们排除了诸如硬件加法器和总线设计这样的主题。虽 然我们谈及了机器语言, 但是重点并不在千如何手工编写汇编语言, 而是关注 C 语言编译器是如何将 C 语言的结构翻译成机器代码的, 包括编译器是如何翻译指针、循环、过程调用以及开关( switch ) 语句的。更进一步地,我们将更广泛和全盘地看待系统,包括硬件和系统软件,涵盖了包 括链接、加载、进程、信号、性能优化、虚拟内存、I/ 0 以 及网络与并发编程等在内的主题。
这种做法使得我们讲授 ICS 课程的方式对学生来讲既实用、具体, 还能动手操作,同 时也非常能调动学生的积极性。很快地,我们收到来自学生和教职工非常热烈而积极的反 响, 我们意识到卡内基-梅隆大学以外的其他人也可以从我们的方法中获益。因此, 这本书从 ICS 课程的笔记中应运而生了, 而现在我们对它做了修改,使 之能 够反映科学技术 以及计算机系统实现中的变化和进步。
通过本书的多个版本和多种语言译本, ICS 和许多相似课程已经成为世界范围内数百所高校的计算机科学和计算机工程课程的一部分。
写给指导教师们:可以基千本书的课程
指导教师可以使用本书来讲授五种不同类型的系统课程(见图 2 ) 。具体每门课程则有
XIX
赖于课程大纲的要求、个人喜好、学生的背景和能力。图中的课程从左往右越来越强调以 程序员的角度来看待系统。以下是简单的描述。
ORG: 一门以非传统风格讲述传统 主题的计算机组成原理课程。传统的 主题包括逻辑设计、处理器体系结构、汇编语言和存储器系统, 然而这里更多地强调了对程序员的影响。例如, 要反过来考虑数据表示对 C 语言程序的数据类型 和操作的影响。又例如 , 对汇编代码的讲解是基于 C 语言编译器产生的机器代码, 而不是手工编写的汇编代码。
ORG+ : 一门 特别强调硬件对应用程序性能影响的 ORG 课程。和 ORG 课程相比, 学生要更多地学习代码优化和改进 C 语言程序的 内存性能。
ICS: 基本的 ICS 课程,旨 在培养一类程序员, 他们能够理解硬件、操作系统和编译系统对应用程序的性能和正确性的影响。和 ORG+ 课程的一个显著不同是, 本课程不涉及低层次的处理器体系结构。相反, 程序员只同现代乱序处理器的高级模型打交道。ICS 课程非常适合安排到一个 10 周的小学期, 如果期望步调更从容一些,也 可以延长到一个 15 周的学期。
ICS+ : 在基本的 ICS 课程基础上, 额外论述一些系统编程的问 题, 比 如系统级1/ 0 、网络编程和并发编程。这是卡内基-梅隆大学的一门一学期时长的课程, 会讲述本书中除了低级处理器体系结构以外的所有章 。
SP: 一门系统编程课程。和 res + 课程相似, 但是剔除了浮点 和性能优化的内容,
更加强调系统编程, 包括进程控制、动态链 接、系统级 1/0 、网络编程和并发编程。指导教师可能会想从其他渠道对某些高级主题做些补充, 比如守护进程( dae m o n ) 、终端控制和 Unix IPC( 进程间通信)。
图 2 要表达的主要信息是本书给了学生和指导教师多种选择。如果你希望学生更多地
图 2 五类基千本书的课程
注: 符 号0 表 示覆 盖部 分章 节 , 其中: ( a) 只 有 硬 件 ; Cb) 无动 态存储 分配; ( c) 无动态链 接 ; Cd) 无孚点 数 。
JCS+ 是卡内基-梅隆的 15-213 课 程 。
xx
了解低层次的处理器体系结 构,那 么 通过 ORG 和 ORG十课程可以达到目的。另一方面, 如果你想将当前的计算机组成原理课程转换成 ICS 或者 ICS+ 课程, 但是又对突然做这样剧烈的变化感到担心, 那么你可以 逐步递增转向 JCS 课程。你可以从 OGR 课程开始,它以一种非传统的方式教授传统的问题。一旦你对这些内容感到驾轻就熟了,就可以转到
ORG+, 最终转到 JCS。如果学生没有 C 语言的经验(比如他们只用 J ava 编写过程序), 你可以 花几周的时间在 C 语言上, 然后再讲述 ORG 或者 JCS 课程的内容。
最后,我们 认为 ORG + 和 SP 课程适合安排为两期(两个小学期或者两个学 期)。或者你可以考虑按照一期 ICS 和一期 SP 的方式来教授 JCS+ 课程。
写给指导教师们:经过课堂验证的实验练习 #
JCS+ 课程在卡内基-梅隆大学得到了学生很高的评价。学生对这门课程的 评价,中 值分 数 一 般为 5. 0/ 5. 0 , 平均分数一般为 4. 6 / 5. 0。学生们说这门课非常有趣, 令人兴奋: 主要就是因为相关的实验练习。这些实验练习可以从 CS: APP 的主页上获得。下面是本书提供的一些实验的示例。
数据实验。这个实验要求学生实现简单的逻辑和算术运算函数, 但是只能使用一个非常有限的 C 语言子集。比如,只 能用位级操作来计算一个数字的绝对值。这个 实验可帮助学生了解 C 语言数据类型的位级表示,以 及 数 据 操 作 的位级行为。
二进制炸 弹实验。二进制 炸 弹是一个作为目标代码文件提供给学生的程序。运行时,它 提示用户输入 6 个不同的字符串。如果其中的任何一个不正确, 炸弹就会
“爆炸",打印出一条错误消息,并且在一个打分服务器上记录事件日志。学生必须 通过对程序反 汇编和逆向工程来测定应该是哪 6 个串,从 而解除各自炸弹的 雷管。该实验能教会学生理解汇编语言,并且强制他们学习怎样使用调试器。
缓冲区溢出实验。它要求学生通过利用一个缓冲区溢出涌洞,来修改一个二进制可 执行文件的运行时行为。这个实验可教会学生栈的原理,并让他们了解写那种易于 遭受缓冲区溢出攻击的代码的危险性。
体系结 构实验。第 4 章的儿个家庭作业能够组合成一个实验作业, 在实验中,学 生修改处理器的 HCL 描述,增 加新的指令, 修改分支预测策略, 或者增加、删除 旁路路径和寄存器端口。修改后的处理器能够被模拟,并通过运行自动化测试检测出 大多数可能的错误。这个实验使学生能够体验处理器设计中令人激动的部分,而不 需要掌握逻辑设计和硬件描述语言的完整知识。
性能实验。学生必须优化应用程序的核心函数(比如卷积积分或矩阵转置)的性能。这 个实验可非常清晰地表明高速缓存的特性,并带给学生低级程序优化的经验。
XXI
- cache 实验。这个实验类似于性能实验,学 生编写一个通用高速缓存模拟器,并 优化小型矩阵转置核心函数,以最小化对模拟的高速缓存的不命中次数。我们使用 Valg r ind 为矩阵转置核心函数生成真实的地址访问记录。
- shell 实验。学生实现他们自己的带有作业控制的 U nix s hell 程序, 包括 Ct rl + C 和Ctrl + Z 按键, f g 、 b g 和 j ob s 命令。这是学生第一次接触并发,并 且 让 他 们 对U nix 的 进程控制、信号和信号处理有清晰的了解。
- ma l l o c 实验。学生实现他们自己的 ma l l o c 、 f r e e 和 r e a l l oc ( 可选)版本。这个实验可让学生们清晰地理解数据的布局和组织,并且要求他们评估时间和空间效率 的各种权衡及折中。
- 代理实验。实现一个位千浏览器和万维网其他部分之间的并行 Web 代理。这个实验向学生们揭示了 Web 客户端和服务器这样的主题,并 且把课程中的许多概念联系起来, 比如字节排序、文件 I/ 0 、进程控制、信号、信号处理、内存映射、套接字和并发。学生很高兴能够看到他们的程序在真实的 Web 浏览器和 Web 服务器之间起到的作用。
CS : A P P 的教师手册中有对实验的详细讨论, 还有关千下载支待软件的说明。
第 3 版的致谢
很荣幸在此感谢那些帮助我们完成本书第 3 版的人们。
. 我们要感谢卡内基-梅隆大学的同事们, 他们已经教授了 ICS 课程多年,并 提 供 了 富有见解的反馈意见,给了我们极大的鼓励: Guy Blell och 、Roger Dan nen ber g、David Eck
hardt 、F ra nz F ra nche tt i、G reg Ga nger 、Set h Golds tein 、Khaled Harr as 、G reg Kesde n、
Bruce Maggs 、T odd Mowr y、And reas Nowatzyk 、F ra nk P fen ning、Mark us P ueschel 和
Anthony Rowe。David Winters 在安装和配置参考 Linux 机器方面给予了我们很大的帮助。
Jason Frit ts ( 圣路易斯大学, S t. Louis Universit y ) 和 Cind y Norris(阿帕拉契州立大学, A ppalach ian S tat e ) 对第 2 版提供了细致周密的评论。龚奕利(武汉大学, W uha n Uni vers it y) 翻译了中文版,并 为其维护勘误,同 时 还贡献了一些错误报告。God mar Back(弗吉尼亚理工大学, V ir gi nia T e ch ) 向我们介绍了异步信号安全以及与协议无关的网络编程, 帮助我 们显著提升了本书质量。
非常感谢目光敏锐的读者们,他 们报告了第 2 版中的错误: Rami Ammari、 P a ul A n ag nost opo ulos 、L ucas Baren fanger 、Godm ar Back、Ji Bin、S har bel Bousemaa n、Rich a r d Callaha n、Set h Chaiken 、Cheng Chen 、Libo C hen 、T ao D u、Pascal Garcia 、Y山 Go ng、
XXII
Ronald G re e n berg 、Doru khan Guloz 、Do ng H an 、Dominik H elm 、Ronald J o nes 、M us ta fa Kazdagli、 Go r don Kindlma nn 、Sa nkar Kris h nan、Kana k Ks het ri 、J unlin Lu、 Q ian gqiang Luo 、Se bas t ia n L uy 、Lei Ma 、As hw in Nanja ppa 、G regoire Para dis 、 J o n as Pfen
ninger 、Karl P icho t t a、 Da vid Rams ey、Ka us ta bh Ro y、 David Selva ra j、 S a nkar Shan mugam 、Dom inique S mulko ws ka 、Dag S0r b0、Michael S pear 、Y u T a naka 、Steven Tri canowic z、Scott W rig h t、Wa如 Wrig ht 、 H an X u 、 Zhengs han Yan 、F iro Ya ng、Sh uang Ya ng 、J o hn Ye、T ak eto Yos hida 、Ya n Zh u 和 M icha el Zin k。
还要感谢对实验做出贡献的读者,他们是: Godmar Back( 弗吉尼亚理工大学, V ir ginia Tech ) 、T aymo n Beal ( 伍斯 特理 工学 院, Worces ter Polytechnic Instit ute ) 、 A ran Cla us o n ( 西 华 盛 顿 大 学, Wes te rn Washington Univer sit y ) 、Ca ry Gray ( 威 顿 学 院, W heaton College ) 、 P a ul H aid uk C 德州农机大学, W es t T e xa s A&M U niversit y ) 、 Len H a mey( 麦考瑞大学 , Macq uar ie U nivers it y) 、Edd ie K oh ler ( 哈佛大学, H a rvard ) 、H ug h L a uer ( 伍斯特理工学院, W o r ces ter Pol ytechnic Ins tit ute ) 、 Ro be rt Marmorst ein( 朗沃德大学, L o ng woo d U nivers it y) 和 James Riely ( 德保罗大学 , D e P a ul U niver si t y) 。
再次感谢 Wind fall 软件公司的 Pa ul A nag nos to po ulo s 在本书排版和先进的制作过程中所做的精湛工作。非常感谢 Pa ul 和他的优秀团队 : Ric hard Camp( 文字编辑)、J enn ifer M c C lain ( 校对)、La ur e l Mull er ( 美术制作)以及 T ed La ux ( 索引 制作)。Pa ul 甚至找出 了我们对缩写 BSS 的起源描述中的一个错误, 这个错误从第 1 版起一直没有被发现!
最后, 我们要感谢 P ren tice H all 出版社的朋友们。Marcia H or to n 和我们的编辑 Matt Golds tein 一直坚定不移地给予我们支持和鼓励, 非常感谢他们。
第 2 版的致谢
我们深深地感谢那些帮助我们写出 CS : AP P 第 2 版的人们。
首先, 我们要感谢在卡内基-梅隆大学教授 ICS 课程的同事们,感 谢 你 们见解深刻的反馈 意 见 和鼓 励: Guy B lelloch 、 R og er Dan nenberg、David E ckhard t、Greg Ganger 、Seth Golds tein 、G reg Ke s de n、Bru ce Maggs 、T odd Mow ry、A nd reas Nowatzyk 、F ra n k P fenni ng 和 Mark us P ues ch el。
还要感谢报告第 1 版勘误的目光敏锐的读者们: Daniel Amelang、Rui Baptista 、 Q uaru p
Barreirinhas 、Michael Bombyk 、Jorg Brauer、Jordan Brough、Yixin Cao、James Caroll、Rui Car
valho、H young-Kee Choi、 Al Davis、Grant Davis 、Christian Dufour、Mao Fan、飞m Freeman、Inge Fr ic k 、 Max Gebhardt、Jeff Goldblat 、T homas Gross 、Anita G upta、John Hampton、Hiep
XXIII
Hong、Greg Israelsen、Ronald Jo nes、Haudy Kazemi、Brian Kell、Constantine Kousoulis、Sacha
Krakowiak 、Arun Krishnaswamy 、Martin Kulas 、Michael Li、Zeyang Li、Ricky Liu 、Mario Lo
Conte、Dirk Maas、Devon Macey、Carl Marcinik、W让I Marrero、Simone Martins 、Tao Men、Mark Morrissey、Venkata Naidu、Bhas Nalabothula、T homas Niemann、Eric Peski n、David Po、Anne Rogers、John Ross、Michael Scott、Se如、Ray Sh巾、 Darre n Shultz、Erik Silkensen、S ury
anto、Emil Tarazi、 Nawanan T heera- Ampornpunt、Joe Trdinich 、Michael Trigobo ff 、 Ja mes
Troup、Martin Vopatek、Alan West、Betsy Wolff 、 T im Wong、James Woodruff 、Scott Wright 、
Jackie 沁ao 、Guanpeng Xu、Qing Xu、Caren Yang、Yin Yongsheng 、Wang Yuanxuan、Steven
Zhang 和 Day Zhong。特别感谢 Inge Frick, 他发现了我们加锁复制Clo ck-and-copy)例子中一个极不明显但很深刻的错误, 还要特别感谢 Ricky Liu, 他的校对水平真的很高。
我们 Int el 实验室的同事 And rew Chien 和 Limor F ix 在本书的写作过程中一直非常支持。非常感谢 S teve Schlosser 提供了一些关于磁盘驱动器的总结描述, Case y H elfr ich 和Michael Ryan 安装并维护了新的 Core i7 机器。Michael Kozuch 、 Ba bu P illai 和 J aso n Ca mpbell 对存储器系统性能、多核系统和能量墙问题提出了很有价值的见解。P hil Gib
bons 和 S himin Chen 跟我们分享了大显关于固态硬盘设计的专业知识。
我们还有机会邀请了 Wen- Mei H w u、M ark us P ueschel 和 J iri S imsa 这样的高人给予了一些针对具体问题的意见和高层次的建议。James Hoe 帮助我们写了 Y86 处 理 器的Ver ilog 描述, 还完成了所有将设计合成到可运行的硬件上的工作。
非常感谢审阅本书草稿的同事们: James Archibal d( 百翰杨大学, Br igham Young Univer
sity) 、Richard Carver( 乔治梅森大学, G eorge Mason Universit y) 、Mirela Damian(维拉诺瓦大学, Vi llanova U niversity) 、Peter Dinda( 西北大学)、John Fiore( 坦普尔大学, Te mple U niver
sity) 、J ason Fritts ( 圣路易斯大学, S t. Louis Universit y) 、Jo hn Greiner( 莱斯大学)、Bria n Har
vey( 加州大学伯克利分校)、Don Heller (宾夕法利亚州立大学)、Wei Chung Hsu(明尼苏达大学)、M呻 elle H ugue( 马里兰大学)、Jeremy Johnson( 德雷克塞尔大学, Drexel U niversity) 、Geoff Kuenning( 哈维马德学院, H ar vey Mudd College) 、Ricky Liu、Sam Madden(麻省理工学院)、Fred Mart in( 马萨诸塞大学洛厄尔分校, U niversity of Massachusetts, Lowell)、Abraham Matta( 波士顿大学)、Markus Pueschel( 卡内基-梅隆大学)、Norman Ramsey(塔夫茨大学, Tufts Universit y) 、Glenn Reinmann( 加州大学洛杉矶分校)、Michela Taufer (特拉华大学, University of Delaware) 和 Craig Zilles ( 伊利诺伊大学香嫔分校)。
Wind fall 软件公司的 Paul A nag nos topoulos 出色地完成了本书的排版,并 领 导 了 制 作团队。非常感谢 Paul 和他超棒的团队: Rick Camp ( 文字编辑)、J oe Snowden(排版)、
XXIV
MaryEllen N. Oliver (校对)、Laurel Muller ( 美术)和T ed Laux ( 索引 制作)。
最后, 我们要感谢 P rent ice Hall 出 版社的朋友们。Marcia H orton 总是支持着我们。我们的编辑 Ma tt Goldst ein 由始至终表现出了一流的领导才能。我们由衷地感谢他们的帮助、鼓励和真知灼见。
第 1 版的致谢
我们衷心地感谢那些给了 我们中肯批评和鼓励的众多朋友及同事。特别感谢我们 15-
213 课程的学生们, 他们充满感染力的精力 和热情鞭策我们前行。Nick Carter 和 Vinny F ur ia 无私地提供了他们的 malloc 程序包。
Guy Blelloch、Greg Kesden、Bruce Maggs 和 T odd Mowr y 己教授此课多个学期, 他们给了我们鼓励并帮助改进课程内容。Her b Der by 提供了早期的精神指导和鼓励。Allan Fis her、Gar t h Gibs on、T homas G ross 、Sat ya 、Peter Stee nk iste 和 H ui Zhang 从一开始就鼓励我们开设 这门课程。Gart h 早期给的建议促使本书的工作得以开展,并 且在 Alla n Fis her 领导的小组的帮助下又细化 和修订了本书的工作。Mar k Stehlik 和 Peter Lee 提供了极大的支持,使 得 这些内容成为本科生课程的 一部分。Greg Kesde n 针对 ICS 在操作系统课程上的影响提供了有益的反馈意见。Greg Ganger 和 J iri Schindler 提供了一些磁盘驱动的描述说明,并 回 答了我们关于现代磁盘的疑问。Tom St riker 向我们展示了存储器山的比喻。James Hoe 在处理器体系结构方面提出了很多有用的建议和反馈。
有一群特殊的学生极大地帮助我们发展了这门课程的内容, 他们是 Khalil Amiri 、Angela Demke Brown、 Chr is Colohan 、Jason Crawfo rd、 Peter Dinda、J ulio Lo pez、Bruce Lowekam p、Jeff Pierce 、San jay Rao、Balaji Sar peshkar 、Blake Scholl、San jit Ses 扣a、Greg Steff an、兀ankai T u、Kip Walker 和 Yinglian X比。尤其是 Chr is Colohan 建立了愉悦的氛围并持续到今天, 还发明了传奇般的“二进制炸弹“,这 是 一个对教授机器语言代码和调试概念非常有用的工具。
Chris Bauer、Ala n Cox 、Peter Dinda 、Sandhya Dwar kadis 、J ohn Greiner 、Bruce Ja cob、Barr y J ohn so n、 Don Heller、 Bru ce Lowekamp 、 Gr eg Morriset t 、 Brian No ble、Bobbie Ot hmer 、Bill P ug h、M呻 ael Scott 、Mark S motherman 、G reg Steff an 和 Bob Wier 花费了大量时间阅读此书的早期草稿, 并 给予 我们建议。特别感谢 Pet er Dinda(西北大学)、John Gre iner ( 莱茨大学)、Wei H s u( 明 尼 苏 达大学)、Bruce Lowekam p( 威廉 & 玛丽大学)、Bobbie O th mer ( 明尼苏达大学)、Michael Scott( 罗彻斯特大学)和Bob Wier ( 落基山学院)在教学中测试此书的试用版。同样特别感谢他们的学生们!
XXV
我们还要 感谢 Prentice H all 出版社的同事。感谢 Marcia H or ton 、 Eric Frank 和 H ar old Stone 不懈的支持和远见。Haro ld 还帮我们 提供了对 RISC 和 CISC 处理器体系结构准确的历史 观点。Jerr y Ralya 有惊人的见识, 并教会了我们很多如何写作的知识。
最后, 我们衷心感谢伟大的技术作家 Brian Ke rnighan 以及后来的 W. Richard Ste
vens, 他们向我们证明了技术书籍也能写得如此优美。谢谢你们所有的人。
Randal E. Bryant David R. O’ Hallaro n
于匹兹 堡, 宾 夕 法尼 亚 州
andal E. Bryant 1973 年于密歇根大学获得学士学位, 随即就读于麻省理工学院研究生院 ,并 在 1981 年获计算机科学博士学位。他
在加州理工学院做了三年助教,从 1 984 年至今一直是卡内基-梅隆大学
的教师。这其中有五年的时间,他是计算机科学系主任,有十年的时间 是计算机科学学院院长。他现在是计算机科学学院的院长、教授。他同 时还受邀任职千电子与计算机工程系。
他教授本科生和研究 生计算机系统 方面的课程近 40 年。在讲授计算机体系结构课程多年后,他开始把关注点从如何设计计算机转移到程序 员如何在更好地了解系统的情况下编写出更有效和更可靠的程序。他和 O ’ H allaro n 教授一起在卡内基-梅隆大学开设 了15- 213 课 程 ”计 算机系统 导论” ,那 便 是 此书的基础。他还教授一些有关算法、编程、计算机网络、分布式系统和 VLSI( 超大规模集成电路)设计方面的课程。
Br yant 教授的主要研究内容是设计软件工具来帮助软件和硬 件设计者验证其系统正确性。其中,包括几种类型的模拟器,以及用数学方法 来证明设计正确性的形式化验证工具。他发表了 150 多篇技术论文。包括 Intel 、IBM 、Fujits u 和 Microso ft 在内的主要计算机制造商都使用着他的研究成果。他还因他的研究获得过数项大奖。其中包括 Semiconductor Research Corpora tion 颁发的两个发明荣誉奖和一个技术成就奖 , ACM 颁发的 Kane llakis 理 论 与 实践 奖, 还 有 IE EE 颁发 的 W. R. G. Baker 奖、Emmanuel Piore 奖和 P hil Kau fman 奖。他还是 ACM 院士、 IEEE 院士、美国国家工程院院士和美国人文与科学研究院院士。
David R. O’ Halla ron 卡内基-梅隆大学计算机科学和电子与计 算机工程系教授 。在弗 吉尼亚大学获得计算机科学博士学位, 2007 ~ 2010 年为In tel 匹兹堡实验室主任。
20 年来 , 他教授本科生和研究生计算机系统 方面的课程,例如 计 算机体系结构、计算机系统导论、并行处理器设计和 Internet 服务。他和 Bry
ant 教授一起在卡内基-梅隆大学开设了作为本 书基础的 ”计 算机系统导论” 课程。2004 年他获得了卡内基-梅隆大学计算机科学学院颁发的 Her bert Simon 杰出教学奖, 这个奖项的获得者是基千学生的 投票产生的。
XXVII #
O’ Hallaro n 教授从事计算机系统领域的研究, 主要兴趣在于科学计算、数据密集型计算和虚拟化方 面的软件系统 。其中最著名的是 Q ua ke 项目,该 项目是一群计算机科学家、土木工程师和地震学 家为提高对强烈 地震中大地运动的预测能力而开发的。2003 年, 他同 Q ua ke 项目中其他成员 一起获得了高性能计算领域中的最高国际奖项—- Gordon Bell 奖。他目前的工作重点是自动分 级( autogra ding ) 概念,即 评价其他程序质量的程序。
目录 #
出版者的话中文版序— 中文版序二译者序
前言关于作者
第 1 章 计算机 系统漫游 1
1.1 信息就是位 十上下文 1
1. 2 程序被其他程序翻译成不同的
格式 3
1. 3 了解 编译 系统 如何 工作 是
大有益处的. 4
处理器读并解释储存在内存
中的指令. 5
4. 1 系统的硬件组成 5
1. 4. 2 运 行 he ll o 程序 7
1.5 高速缓存至关重要 ......… 9
1.6 存储设备形成层次结构 9
7 操作系统管理硬件 1 0
1. 7. 1 进程. 11
1. 7. 2 线程. 1 2
1. 7. 3 虚拟内存. 12
1. 7. 4 文件. 14
- 系统 之间 利用网络通信 1 4
- 重要主题 16
9. 1 A mda hl 定律 1 6
1. 9. 2 并发和并行. 1 7
9. 3 计 算机 系统 中抽 象的
重要性. 19
1. 1 0 小结. 20
参 考文献说明 20
练习题答案 20
第一部分 #
程序结构和执行 #
第 2 章 信息的表示和处理 22
1 信息存储 24
2. 1. 1 十六进 制表示 法 25
2. 1. 2 宇 数 据 大小 27
2. 1. 3 寻址和宇节顺序 29
2. 1. 4 表示宇符 串 34
2. 1. 5 表示代码 34
2. 1. 6 布 尔代数简 介 35
XXIX #
1. 7 C 语言中的位级运算 … … … 37
2. 1. 8 C 语 言中的逻辑运算 … … … 39
2. 1. 9 C 语 言中的移位运算 40
2. 2 整数表示 4.1
2. 2. 1 整 型数据类型 42
2. 2. 2 无符号数的编码. 43
2. 2. 3 补码 编码 44
2. 2. 4 有符号数和无符号数之间的
转换 49
2. 2. 5 C 语 言中的 有符号数与
无符号数. 52
2. 2. 6 扩展 一个数宇的位表示 … … 54
2. 2. 7 截 断数 宇 56
2. 2. 8 关于有符号数与无符号数的
建议. 58
3 整数运 算 60
2. 3. 1 无符号加法. 60
2. 3. 2 补码加 法 62
2. 3. 3 才卜码 的非 66
2. 3. 4 无符号乘法……······" 67
2. 3. 5 补码乘法. 67
2. 3. 6 乘以常数. 70
2. 3. 7 除 以 2 的幕 71
3 . 8 关于整数 运算的最后思考… … 74
3. 2. 3 关于格式的注解 ....….….117
3. 3 数据格式 .·. ..·..·…·..···..· 119
3.4 访问 信 息 ···..·…… ·..······..··.. 119
3. 4. 1 操作数指示符 121
3. 4. 2 数据传送指令 122
3. 4. 3 数据传送示例 125
3. 4. 4 压入和弹出栈数据 …… … 127
5 算术和逻辑操作 128
3. 5. 1 加栽有效地址 1.29
3. 5. 2 一 元和二元操作 130
3. 5. 3 移位操作 1.31
3. 5. 4 讨论..····..·..·…·..·..·..·.. 131
3. 5 . 5 特殊的算术操作 133
3. 6 控 制 135
3. 6. 1 条件码·….·..·………·. 135
3. 6. 2 访问条件码 136
3. 6. 3 跳 转指令 138
3. 6. 4 跳转指令的编码 1 39
3. 6. 5 用条件控制来 实现 条件分支 … 1 41
3. 6. 6 用条件 传送来实现 条件分支 … 145 3. 6. 7 循环 1.49
3. 6. 8 switch 语 句 ..·..·….. ···… 159
3. 7 过程. 164
3 . 7. 1 运 行 时栈 164
2.4 浮点数 …………………………. | 75 | 3. 7. 2 | 转移控制 | ……………… 165 |
---|---|---|---|---|
2. 4. 1 二 进 制 小数 ………… …….. | 76 | 3. 7. 3 | 数据传送 | ………..……… 168 |
2. 4. 2 IEEE 浮点表 示 78
2. 4. 3 数 字示例 79
2. 4. 4 舍入. 83
2. 4. 5 浮点运 算 85
4. 6 C 语 言 中的 浮点数 86
2. 5 小结 87
参考文献说明 88
家 庭作业 ………..· 88
练习题答案 9.7
7. 4 栈上的局部存储 170
3. 7. 5 寄存器中的局部存储空间 … 172 3. 7. 6 递归过程. 174
3. 8 数组分配和访问 1.76
3. 8. 1 基本原则 176
3. 8. 2 指针运 算 177
3. 8. 3 嵌 套 的数 组 178
3. 8. 4 定长数组. 179
3. 8 . 5 变长 数组 1.8.1.
3. 9 异质的数据结构 183
第 3 章 程序的机器级表示……·..···… 1 09
3. 1 历史观点 110
3. 2 程序编码 113
3. 2. 1 机器级代码 1 13
3. 2. 2 代码示例 …·..·..·..·…….· 11 4
3 . 9. 1 结构. 183
3 . 9. 2 联合. 1 8 6
3. 9. 3 数据 对 齐 189
3. 10 在机器级程序中将控制与
数据结合起来 1.9.2
XXX #
3. 10. 1 理解指针. 192
3. 10. 2 应用: 使 用 GDB调试器 … 193
3. 10. 3 内存越界引用和缓冲区
溢出. 194
3. 10. 4 对抗缓 冲 区 溢 出攻 击 … … 198 3. 10. 5 支持变长栈帧. 201
3. 11 浮点代码 204
11. 1 浮点传送 和转换操作 … … 205
4.4 流水线的通用原理 282
4. 4. 1 计算流水线 282
4. 2 流水线操作的详细说明 … 284 4. 4. 3 流水线的局限性 284
4. 4. 4 带反馈的流水线系统 287
4. 5 Y86- 64 的 流 水 线 实 现 288
4. 5. 1 SEQ + : 重新安排计算
阶段 288
3 . 1 2 小结 216
参考文献说 明 216
家庭作业 2.16
练习题 答案 226
第 4 章 处理器体系结构 243
4. 1 Y86-64 指 令 集体 系结构 … … … 245
4. 1. 1 程序员可见的状态 ……… 245
4. 1. 2 Y86-64 指令 ……………2..4.5
4. 1. 3 指令编码. 246
4. 1. 4 Y86-64 异常 250
4. 1. 5 Y86-64 程序 ..·. …·. ..·. 251
4. 1. 6 一些 Y86-64指令的详情 … … 255
4.2 逻辑设计和硬件控制语言 HCL … 256 4. 2. 1 逻辑门. 257
4. 2. 2 组合电路和 HCL 布 尔
表 达 式 257
4. 2. 3 宇级的 组合 电路和 HCL
整数表达式 258
4. 2. 4 集合关系 261
4. 2. 5 存储器和时钟 262
4. 3 Y86-64 的 顺 序实现 2.6.4
4. 3. 1 将处理组织成阶段 ……… 264
4. 3. 2 SEQ 硬件结构 272
4. 3. 3 SEQ 的 时序 274
4. 3. 4 SEQ 阶段 的 实现 ......... 2…77
5 . 8 流水线控制逻辑 314
4. 5. 9 性能分析. 322
4. 5. 10 未完成的工作 323
4 . 6 ; \j 结 325
参考文献说明 326
家庭作业 327
练习题 答案 331
第 5 章 优化程序性能 … … … … … 3 41
1 优化编译器的能力和局限性 … 342 5. 2 表示程序性 能 345
5. 3 程序示例 347
5. 4 消除循环的低效率 350
5. 5 减 少过程调用 353
5. 6 消除不必要的内存引用 354
5. 7 理解现代处理器 357
5. 7. 1 整体操作 357
5. 7. 2 功能单元的性能 361
5. 7. 3 处理器操作的抽象模型 … 362 5. 8 循环展开 366
5. 9 提高并行性 3.6.9.
5. 9. 1 多个累积变量 3.70
5. 9. 2 重新结合变换 373
5. 10 优化合并代码的结果小结 377
5. 11 一 些限制 因素 378
5. 11. 1 寄存 器溢出 378
XXXI
5. 11. 2 分 支预 测和预 测错 误
处罚 3 79
5. 12 理 解内存性能 382
5. 12. 1 加 载的性能 382
5. 12. 2 存 储 的性 能 383
5. 13 应用:性 能 提高技术 387
14 确认和消除性能瓶颈 388
5. 14. 1 程序剖析 388
14. 2 使用剖析程序来指导
3 存储器层次结构 421
6. 3. 1 存储器层 次 结构中的缓存 … 422
6. 3. 2 存储器层 次 结构概 念小结 … 424 6. 4 高速缓存存储器 425
6. 4. 1 通用的 高速缓存存储 器
组织结构 42 5
6. 4. 2 直接映射高速缓存 427
6. 4. 3 组相联高速缓存 433
6. 4. 4 全相联高速缓存 434
练习题答案… .. . … … … … … … .. . .. . .. . 39 ;:i
第 6 章 存 储 谣 层 次 结 构 399
6. 1 存储技术 399
6. 1. 1 随机访问存储 器 40 0
6. 1. 2 磁 盘 存 储 .··· 406
6. 1. 3 固态硬盘 414
6. 1. 4 存储技术趋势 ………..·..· 415
6. 2 局 部 性 . .. . .. . .. . .. .. . .. . . . · .. . .. · .. . 4 1 8
6. 2. 1 对程序数据引用的 局部性 … 41 8 6. 2. 2 取 指 令 的局部性 419
6. 2. 3 局部性小结 420
5 编写高速缓存友好的代码 … … 440
6. 6 综合 : 高 速缓存对程序性能的
影响 444
6. 6. 1 存储器 山 444
6. 6. 2 重新排列循环以提高空间
局部性 447
6. 3 在程序中利 用局 部 性 450
6. 7 小结 4.50….
参考文献说 明 45 1
家庭作业 45 1
练习题答案 459
第二部 分 #
在系统上运行程序 #
第 7 章 链接 464
1 编译器驱动程序 465
7. 2 静态链接 466
7. 3 目标文件 466
7. 4 可重定位目标文件 4 67
7. 5 符号和符号表 468
7. 6 符号解析 470
7. 6. 1 链接器如何解析多重定义
的全局符号 471
7. 6. 2 与静 态库 链 接 475
7. 7 重定位 478
7. 7. 1 重定位条 目 479
7. 7. 2 重定位符号引用 .... 479
7. 8 可执行目标文件 483
7. 9 加载可执行目标文件 484
7. 10 动态链接共享库 485
7. 11 从应用程序中加载和链接
共享库 487
7. 12 位置无关代码 489
7. 13 库打桩机制 492
7. 6. 3 链接器如何使用静态库来
7. 13. 1 编译 时打桩 …………….
492
解析弓l 用 477
7. 13. 2 链 接 时打 桩 ……………_… 492
XXXII #
7. 13. 3 运行时打桩. 494
14 处理目标文件的工具. 496
7. 15 小结. 496
参考文献说 明 497
家庭作业 497
练习题答案. 499
第 8 章 异常控制 流 50 1
8. 1 异常. 502
8. 1. 1 异常处理. 503
8. 1. 2 异常的类别 504
1. 3 Linux / x86-64 系统 中的
异常. 505
8. 2 进程. 508
8. 2. 1 逻样控制流 508
8. 2. 2 并发流. 509
8.2. 3 私有地址空间 509
8. 2. 4 用户模式和内核模式 …… 510 8. 2. 5 上下文切换 511
8. 3 系统调用错误处理 512
8. 4 进程控制. 513
8. 4. 1 获 取 进 程 ID 513
8. 4.2 创建和终止进程 513
8. 4. 3 回收子进程 516
8. 4. 4 让进程休眠. 521
8. 4. 5 加栽并运行程序 52 1
8. 4. 6 利 用 f or k 和 e xe cve 运行
程序. 524
8. 5 信号 526
8. 5. 1 信号术语. 527
8. 5. 2 发送信号. 528
8. 5. 3 接收信号. 531
8. 5. 4 阻塞和解除阻塞信号 …… 532 8. 5. 5 编写信号处理程序 ……… 533
8. 5. 6 同步流以避免讨厌的并发
错误. 540
8. 5. 7 显式地等待信号 543
8. 6 非本地跳转. 546
7 操作进程的工具… 550
8. 8 小结. 550
参考文献说 明 550
家庭作业 5.5.0..
练习题答案. 556
第 9 章 虚拟内存 559
- 1 物理和虚拟寻址 560
9. 2 地址空间. 560
9. 3 虚拟内存作为缓存的工具 …… 561
9. 3. 1 DRAM 缓存的组织结构 … … 562 9. 3. 2 页表. 562
9. 3. 3 页命中. 563
9. 3. 4 缺页. 564
9. 3. 5 分配页面 …···.·..·…· 565
9. 3. 6 又是局部性救了我们 565
9. 4 虚拟内存作为内存管理的
工具 565
9. 5 虚拟内存作为内存保护的
工具 5.6.7…
9. 6 地址翻译. 567
9. 6. 1 结合高速缓存和虚拟
内存. 570
9. 6. 2 利 用 T LB 加速地址翻译 … … 570 9. 6. 3 多级页表. 571
9. 6. 4 综合:端到端的地址翻译 … 573
9. 7 案例研究: Intel Core i7/ Linux
内存系统. 576
9. 7. 1 Core i7 地址翻译 5.76
9. 7. 2 Lin ux 虚拟内存 系统 … … … 580
9.8 内存映射 582
9. 8. 1 再看共享对象 583
9. 8. 2 再 看 f or k 函数 5.84
9. 8. 3 再 看 e xe c ve 函数. 584
9. 8. 4 使 用 mma p 函 数 的 用 户级
内存映射 585
9. 9 动态内存分配. 587
9. 9. 1 ma ll o c 和 f r e e 函数 … … 587
9. 9. 2 为什么要使用动态内存
分配. 589
9. 9. 3 分配器的要求和目标 … … 590 9. 9. 4 碎片. 591
9. 9. 5 实现问题. 592
9. 9. 6 隐式空闲链表. 592
9. 9. 7 放置已分配的块 593
9. 9. 8 分割空闲块 594
- 9. 9 获取额外的堆内存 594
XXXIII #
Sweep 608
9.11 C 程序中常见的与内存有关的
错误 609
9. 11. 1 间接引用坏指针. 609
9. 12 小结 613
参考文献说明 613
家庭作业 614
练习题答案. 617
第三部分 #
程序间的交互和通信 #
第 10 章 系统级 1 /0 622
10. 1 Unix I/ 0 622
10. 2 文 件 623
3 打开和关闭文件. 624
10. 4 读 和 写 文 件 625
10. 5 用 RIO 包 健 壮 地读写 626
10. 5. 1 RIO 的无缓 冲的 输入4俞出
函数 627
10. 5. 2 RIO 的带缓 冲的轮入
函数. 627
10. 6 读 取 文 件 元 数 据 632
7 读 取 目 录内容 633
10. 8 共享文件 634
10. 9 I/ 0 重定向 637
第 11 农 网络编程 642
1 客户端-服务器编程模型 … … 642 11. 2 网络. 643
11. 3 全球 IP 因特网 646
11.3.1 IP 地址 647
11. 3. 2 因 特 网域 名 649
11. 3. 3 因特 网连 接 651
11. 4 套 接字接口 652
11. 4. 1 套接字地 址 结构 653
11. 4. 2 s oc ke t 函数 654
11. 4. 3 c onne c t 函数 654
11. 4. 4 bi nd 函数 654
11. 4. 5 li s t e n 函数 655
11. 4. 6 a c c e p七函 数 655
11. 4. 7 主机和服务的转换 … … … 656
参考文献说 明 640
家庭作业 6.40
练习题答案 641
11.5.1 Web 基础. 665
11. 5. 2 Web 内容 666
11. 5. 3 HTT P 事务 667
XXXIV
11. 5. 4 服务动 态内容 669
6 综合: TINY Web 服务器. 671
11. 7 小结. 6.7.8 …..
12. 4. 1 线程内存模型. 696
12. 4. 2 将 变 量映射到内存 … … … 697 12. 4. 3 共享变量. 698
参考文献说明. 678
家庭作业 678
练习题答案. 679
第 1 2 章 并发编程 681
1 基 千 进程 的并 发 编程 682
12. 1. 1 基于进程的并发服务器 … 683 12. 1. 2 进程的优劣. 684
12.2 基千I/0 多路复用的并发
编程. 684
12. 2. 1 基于 I/ 0 多 路 复 用的并发
事件驱动服务器… 686
12. 2. 2 I/ 0 多路 复 用技 术的优劣 … 690
12. 3 基于线程的并发编程 691
12. 3. 1 线程执行模型. 691
12. 3. 2 Posix 线程 691
12. 3. 3 创 建线程 6.92
12. 3.4 终止线程. 693
12. 3. 5 回收己终止线程的资源 … 693 12. 3. 6 分 离 线程 694
12. 3. 7 初始化线程. 694
12. 3. 8 基于线程的并发
服务器. 694
12. 4 多线程程序中的共享变批 … … 696
12. 5 用信号量同步线程 698
12. 5. 1 进度图. 701
1 2. 5. 2 信号量 702
12. 5. 3 使用信号量来实现互斥 … 703
12. 5. 4 利用信号量来调度共享
资源. 704
12. 5. 5 综合:基于预线程化的
并发服务器. 708
12. 6 使 用 线 程提高并行性 710
12. 7 其他并发问题. 716
12. 7. 1 线程安全 716
12. 7. 2 可重入性. 717
12. 7. 3 在线程化的程序中使用
已存在的库函数 718
12. 7. 4 竞争. 719
12. 7. 5 死锁 721
12. 8 小结. 722
参考文献说明. 723
家庭作业 723
练习题答案. 726
附录 A 错误处理 729
参考文献 733