本書是將計算機軟件和硬件理論結合講述的經典教程,內容覆蓋計算機導論、體系結構和處理器設計等多門課程。本書的大優(yōu)點是為程序員描述計算機系統(tǒng)的實現(xiàn)細節(jié),通過描述程序是如何映射到系統(tǒng)上,以及程序是如何執(zhí)行的,使讀者更好地理解程序的行為為什么是這樣的,以及造成效率低下的原因。
第二版銷售突破100000冊,第三版重磅上市!
理解計算機系統(tǒng)首*書目, 10余萬程序員的共同選擇
卡內基-梅隆、北京大學、清華大學、上海交通大學等國內外眾多知名高校選用指定教材
從程序員視角全面剖析的實現(xiàn)細節(jié),使讀者深刻理解程序的行為,將所有計算機系統(tǒng)的相關知識融會貫通。
新版本全面基于X86-64位處理器
全新的閱讀和學習體驗:由國內名師錄制章前導讀,使讀者可以了解各章的重點內容和知識關聯(lián),形成關于計算機系統(tǒng)的知識架構。并開設了本書的網絡社區(qū),讀者可加入社區(qū),獲得本書相關學習資源,了解活動信息。
前言
本書(簡稱CS:APP)的主要讀者是計算機科學家、計算機工程師,以及那些想通過學習計算機系統(tǒng)的內在運作而能夠寫出更好程序的人。
我們的目的是解釋所有計算機系統(tǒng)的本質概念,并向你展示這些概念是如何實實在在地影響應用程序的正確性、性能和實用性的。其他的系統(tǒng)類書籍都是從構建者的角度來寫的,講述如何實現(xiàn)硬件或系統(tǒng)軟件,包括操作系統(tǒng)、編譯器和網絡接口。而本書是從程序員的角度來寫的,講述應用程序員如何能夠利用系統(tǒng)知識來編寫出更好的程序。當然,學習一個計算機系統(tǒng)應該做些什么,是學習如何構建一個計算機系統(tǒng)的很好的出發(fā)點,所以,對于希望繼續(xù)學習系統(tǒng)軟硬件實現(xiàn)的人來說,本書也是一本很有價值的介紹性讀物。大多數(shù)系統(tǒng)書籍還傾向于重點關注系統(tǒng)的某一個方面,比如:硬件架構、操作系統(tǒng)、編譯器或者網絡。本書則以程序員的視角統(tǒng)一覆蓋了上述所有方面的內容。
如果你研究和領會了這本書里的概念,你將開始成為極少數(shù)的“牛人”,這些“牛人”知道事情是如何運作的,也知道當事情出現(xiàn)故障時如何修復。你寫的程序將能夠更好地利用操作系統(tǒng)和系統(tǒng)軟件提供的功能,對各種操作條件和運行時參數(shù)都能正確操作,運行起來更快,并能避免出現(xiàn)使程序容易受到網絡攻擊的缺陷。同時,你也要做好更深入探究的準備,研究像編譯器、計算機體系結構、操作系統(tǒng)、嵌入式系統(tǒng)、網絡互聯(lián)和網絡安全這樣的高級題目。
讀者應具備的背景知識
本書的重點是執(zhí)行x86-64機器代碼的系統(tǒng)。對英特爾及其競爭對手而言,x86-64是他們自1978年起,以8086微處理器為代表,不斷進化的最新成果。按照英特爾微處理器產品線的命名規(guī)則,這類微處理器俗稱為“x86”。隨著半導體技術的演進,單芯片上集成了更多的晶體管,這些處理器的計算能力和內存容量有了很大的增長。在這個過程中,它們從處理16位字,發(fā)展到引入IA32處理器處理32位字,再到最近的x86-64處理64位字。
我們考慮的是這些機器如何在Linux操作系統(tǒng)上運行C語言程序。Linux是眾多繼承自最初由貝爾實驗室開發(fā)的Unix的操作系統(tǒng)中的一種。這類操作系統(tǒng)的其他成員包括Solaris、FreeBSD和MacOS X。近年來,由于Posix和標準Unix規(guī)范的標準化努力,這些操作系統(tǒng)保持了高度兼容性。因此,本書內容幾乎直接適用于這些“類Unix”操作系統(tǒng)。
文中包含大量已在Linux系統(tǒng)上編譯和運行過的程序示例。我們假設你能訪問一臺這樣的機器,并且能夠登錄,做一些諸如切換目錄之類的簡單操作。如果你的計算機運行的是Microsoft Windows系統(tǒng),我們建議你選擇安裝一個虛擬機環(huán)境(例如VirtualBox或者VMWare),以便為一種操作系統(tǒng)(客戶OS)編寫的程序能在另一種系統(tǒng)(宿主OS)上運行。
我們還假設你對C和C++有一定的了解。如果你以前只有Java經驗,那么你需要付出更多的努力來完成這種轉換,不過我們也會幫助你。Java和C有相似的語法和控制語句。不過,有一些C語言的特性(特別是指針、顯式的動態(tài)內存分配和格式化I/O)在Java中都是沒有的。所幸的是,C是一個較小的語言,在Brian Kernighan和Dennis Ritchie經典的“K&R”文獻中得到了清晰優(yōu)美的描述\[61\]。無論你的編程背景如何,都應該考慮將K&R作為個人系統(tǒng)藏書的一部分。如果你只有使用解釋性語言的經驗,如Python、Ruby或Perl,那么在使用本書之前,需要花費一些時間來學習C。
本書的前幾章揭示了C語言程序和它們相對應的機器語言程序之間的交互作用。機器語言示例都是用運行在x86-64處理器上的GNU GCC編譯器生成的。我們不需要你以前有任何硬件、機器語言或是匯編語言編程的經驗。
給C語言初學者 關于C編程語言的建議
為了幫助C語言編程背景薄弱(或全無背景)的讀者,我們在書中加入了這樣一些專門的注釋來突出C中一些特別重要的特性。我們假設你熟悉C++或Java。
Randal E. Bryant,1981年于麻省理工學院獲得計算機博士學位,1984年至今一直任教于卡內基-梅隆大學,F(xiàn)任卡內基-梅隆大學計算機科學學院院長、教授,同時還受邀任教于電子和計算機工程系。他從事本科生和研究生計算機系統(tǒng)方面課程的教學近40年。他和O’Hallaron教授一起在卡內基梅隆大學開設了15-213課程“計算機系統(tǒng)導論”,那便是本書的基礎。他還是ACM院士、IEEE院士、美國國家工程院院士和美國人文與科學研究院院士。其研究成果被Intel、IBM、Fujitsu和Microsoft等主要計算機制造商使用,他還因研究獲得過Semiconductor Research Corporation、ACM、IEEE頒發(fā)的多項大獎。
David R. O’Hallaron卡內基梅隆大學電子和計算機工程系教授。在弗吉尼亞大學(University of Virginia)獲得計算機科學的博士學位,2007年-2010年為Intel匹茲堡實驗室主任。他教授本科生和研究生的計算機系統(tǒng)方面的課程已有20余年,并和Bryant教授一起開設了“計算機系統(tǒng)導論”課程。曾獲得CMU計算機學院頒發(fā)的Herbert Simon杰出教學獎。他主要從事計算機系統(tǒng)領域的研究,與Quake項目成員一起獲得過高性能計算領域中的*高國際獎項——Gordon Bell獎。他目前的工作重點是研究自動分級(autograding)概念,即評價其他程序質量的程序。
目錄
出版者的話
中文版序一
中文版序二
譯者序
前言
關于作者
第1章 計算機系統(tǒng)漫游1
1.1 信息就是位+上下文1
1.2 程序被其他程序翻譯成不同的格式3
1.3 了解編譯系統(tǒng)如何工作是大有益處的4
1.4 處理器讀并解釋儲存在內存中的指令5
1.4.1 系統(tǒng)的硬件組成5
1.4.2 運行hello程序7
1.5 高速緩存至關重要9
1.6 存儲設備形成層次結構9
1.7 操作系統(tǒng)管理硬件10
1.7.1 進程11
1.7.2 線程12
1.7.3 虛擬內存12
1.7.4 文件14
1.8 系統(tǒng)之間利用網絡通信14
1.9 重要主題16
1.9.1 Amdahl定律16
1.9.2 并發(fā)和并行17
1.9.3 計算機系統(tǒng)中抽象的重要性19
1.10 小結20
參考文獻說明20
練習題答案20
第一部分
程序結構和執(zhí)行
第2章 信息的表示和處理22
2.1 信息存儲24
2.1.1 十六進制表示法25
2.1.2 字數(shù)據大小27
2.1.3 尋址和字節(jié)順序29
2.1.4 表示字符串34
2.1.5 表示代碼34
2.1.6 布爾代數(shù)簡介35
2.1.7 C語言中的位級運算37
2.1.8 C語言中的邏輯運算39
2.1.9 C語言中的移位運算40
2.2 整數(shù)表示41
2.2.1 整型數(shù)據類型42
2.2.2 無符號數(shù)的編碼43
2.2.3 補碼編碼44
2.2.4 有符號數(shù)和無符號數(shù)之間的轉換49
2.2.5 C語言中的有符號數(shù)與無符號數(shù)52
2.2.6 擴展一個數(shù)字的位表示54
2.2.7 截斷數(shù)字56
2.2.8 關于有符號數(shù)與無符號數(shù)的建議58
2.3 整數(shù)運算60
2.3.1 無符號加法60
2.3.2 補碼加法62
2.3.3 補碼的非66
2.3.4 無符號乘法67
2.3.5 補碼乘法67
2.3.6 乘以常數(shù)70
2.3.7 除以2的冪71
2.3.8 關于整數(shù)運算的最后思考74
2.4 浮點數(shù)75
2.4.1 二進制小數(shù)76
2.4.2 IEEE浮點表示78
2.4.3 數(shù)字示例79
2.4.4 舍入83
2.4.5 浮點運算85
2.4.6 C語言中的浮點數(shù)86
2.5 小結87
參考文獻說明88
家庭作業(yè)88
練習題答案97
第3章 程序的機器級表示109
3.1 歷史觀點110
3.2 程序編碼113
3.2.1 機器級代碼113
3.2.2 代碼示例114
3.2.3 關于格式的注解117
3.3 數(shù)據格式119
3.4 訪問信息119
3.4.1 操作數(shù)指示符121
3.4.2 數(shù)據傳送指令122
3.4.3 數(shù)據傳送示例125
3.4.4 壓入和彈出棧數(shù)據127
3.5 算術和邏輯操作128
3.5.1 加載有效地址129
3.5.2 一元和二元操作130
3.5.3 移位操作131
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 跳轉指令的編碼139
3.6.5 用條件控制來實現(xiàn)條件分支…141
3.6.6 用條件傳送來實現(xiàn)條件分支…145
3.6.7 循環(huán)149
3.6.8 switch語句159
3.7 過程164
3.7.1 運行時棧164
3.7.2 轉移控制165
3.7.3 數(shù)據傳送168
3.7.4 棧上的局部存儲170
3.7.5 寄存器中的局部存儲空間172
3.7.6 遞歸過程174
3.8 數(shù)組分配和訪問176
3.8.1 基本原則176
3.8.2 指針運算177
3.8.3 嵌套的數(shù)組178
3.8.4 定長數(shù)組179
3.8.5 變長數(shù)組181
3.9 異質的數(shù)據結構183
3.9.1 結構183
3.9.2 聯(lián)合186
3.9.3 數(shù)據對齊189
3.10 在機器級程序中將控制與數(shù)據結合起來192
3.10.1 理解指針192
3.10.2 應用:使用GDB調試器193
3.10.3 內存越界引用和緩沖區(qū)溢出194
3.10.4 對抗緩沖區(qū)溢出攻擊198
3.10.5 支持變長棧幀201
3.11 浮點代碼204
3.11.1 浮點傳送和轉換操作205
3.11.2 過程中的浮點代碼209
3.11.3 浮點運算操作210
3.11.4 定義和使用浮點常數(shù)212
3.11.5 在浮點代碼中使用位級操作212
3.11.6 浮點比較操作213
3.11.7 對浮點代碼的觀察結論215
3.12 小結216
參考文獻說明216
家庭作業(yè)216
練習題答案226
第4章 處理器體系結構243
4.1 Y86-64指令集體系結構245
4.1.1 程序員可見的狀態(tài)245
4.1.2 Y86-64指令245
4.1.3 指令編碼246
4.1.4 Y86-64異常250
4.1.5 Y86-64程序251
4.1.6 一些Y86-64指令的詳情255
4.2 邏輯設計和硬件控制語言HCL256
4.2.1 邏輯門257
4.2.2 組合電路和HCL布爾表達式257
4.2.3 字級的組合電路和HCL整數(shù)表達式258
4.2.4 集合關系261
4.2.5 存儲器和時鐘262
4.3 Y86-64的順序實現(xiàn)264
4.3.1 將處理組織成階段264
4.3.2 SEQ硬件結構272
4.3.3 SEQ的時序274
4.3.4 SEQ階段的實現(xiàn)277
4.4 流水線的通用原理282
4.4.1 計算流水線282
4.4.2 流水線操作的詳細說明284
4.4.3 流水線的局限性284
4.4.4 帶反饋的流水線系統(tǒng)287