第二版銷(xiāo)售突破100000冊,第三版重磅上市!
理解計算機系統首*書(shū)目, 10余萬(wàn)程序員的共同選擇
卡內基-梅隆、北京大學(xué)、清華大學(xué)、上海交通大學(xué)等國內外眾多知名高校選用指定教材
從程序員視角全面剖析的實(shí)現細節,使讀者深刻理解程序的行為,將所有計算機系統的相關(guān)知識融會(huì )貫通。
新版本全面基于X86-64位處理器
全新的閱讀和學(xué)習體驗:由國內名師錄制章前導讀,使讀者可以了解各章的重點(diǎn)內容和知識關(guān)聯(lián),形成關(guān)于計算機系統的知識架構。并開(kāi)設了本書(shū)的網(wǎng)絡(luò )社區,讀者可加入社區,獲得本書(shū)相關(guān)學(xué)習資源,了解活動(dòng)信息。
和第2版相比,本版內容上*大的變化是,從以IA32和x86-64為基礎轉變?yōu)橥耆詘86-64為基礎。主要更新如下:
基于x86-64,大量地重寫(xiě)代碼,首次介紹對處理浮點(diǎn)數據的程序的機器級支持。
處理器體系結構修改為支持64位字和操作的設計。
引入更多的功能單元和更復雜的控制邏輯,使基于程序數據流表示的程序性能模型預測更加可靠。
擴充關(guān)于用GOT和PLT創(chuàng )建與位置無(wú)關(guān)代碼的討論,描述了更加強大的鏈接技術(shù)(比如庫打樁)。
增加了對信號處理程序更細致的描述,包括異步信號安全的函數等。
采用新函數,更新了與協(xié)議無(wú)關(guān)和線(xiàn)程安全的網(wǎng)絡(luò )編程。
Randal E. Bryant,1981年于麻省理工學(xué)院獲得計算機博士學(xué)位,1984年至今一直任教于卡內基-梅隆大學(xué)?,F任卡內基-梅隆大學(xué)計算機科學(xué)學(xué)院院長(cháng)、教授,同時(shí)還受邀任教于電子和計算機工程系。他從事本科生和研究生計算機系統方面課程的教學(xué)近40年。他和O’Hallaron教授一起在卡內基梅隆大學(xué)開(kāi)設了15-213課程“計算機系統導論”,那便是本書(shū)的基礎。他還是ACM院士、IEEE院士、美國國家工程院院士和美國人文與科學(xué)研究院院士。其研究成果被Intel、IBM、Fujitsu和Microsoft等主要計算機制造商使用,他還因研究獲得過(guò)Semiconductor Research Corporation、ACM、IEEE頒發(fā)的多項大獎。
David R. O’Hallaron卡內基梅隆大學(xué)電子和計算機工程系教授。在弗吉尼亞大學(xué)(University of Virginia)獲得計算機科學(xué)的博士學(xué)位,2007年-2010年為Intel匹茲堡實(shí)驗室主任。他教授本科生和研究生的計算機系統方面的課程已有20余年,并和Bryant教授一起開(kāi)設了“計算機系統導論”課程。曾獲得CMU計算機學(xué)院頒發(fā)的Herbert Simon杰出教學(xué)獎。他主要從事計算機系統領(lǐng)域的研究,與Quake項目成員一起獲得過(guò)高性能計算領(lǐng)域中的*高國際獎項——Gordon Bell獎。他目前的工作重點(diǎn)是研究自動(dòng)分級(autograding)概念,即評價(jià)其他程序質(zhì)量的程序。
出版者的話(huà)
中文版序一
中文版序二
譯者序
前言
關(guān)于作者
第1章 計算機系統漫游1
1.1 信息就是位+上下文1
1.2 程序被其他程序翻譯成不同的格式3
1.3 了解編譯系統如何工作是大有益處的4
1.4 處理器讀并解釋儲存在內存中的指令5
1.4.1 系統的硬件組成5
1.4.2 運行hello程序7
1.5 高速緩存至關(guān)重要9
1.6 存儲設備形成層次結構9
1.7 操作系統管理硬件10
1.7.1 進(jìn)程11
1.7.2 線(xiàn)程12
1.7.3 虛擬內存12
1.7.4 文件14
1.8 系統之間利用網(wǎng)絡(luò )通信14
1.9 重要主題16
1.9.1 Amdahl定律16
1.9.2 并發(fā)和并行17
1.9.3 計算機系統中抽象的重要性19
1.10 小結20
參考文獻說(shuō)明20
練習題答案20
第一部分
程序結構和執行
第2章 信息的表示和處理22
2.1 信息存儲24
2.1.1 十六進(jìn)制表示法25
2.1.2 字數據大小27
2.1.3 尋址和字節順序29
2.1.4 表示字符串34
2.1.5 表示代碼34
2.1.6 布爾代數簡(jiǎn)介35
2.1.7 C語(yǔ)言中的位級運算37
2.1.8 C語(yǔ)言中的邏輯運算39
2.1.9 C語(yǔ)言中的移位運算40
2.2 整數表示41
2.2.1 整型數據類(lèi)型42
2.2.2 無(wú)符號數的編碼43
2.2.3 補碼編碼44
2.2.4 有符號數和無(wú)符號數之間的轉換49
2.2.5 C語(yǔ)言中的有符號數與無(wú)符號數52
2.2.6 擴展一個(gè)數字的位表示54
2.2.7 截斷數字56
2.2.8 關(guān)于有符號數與無(wú)符號數的建議58
2.3 整數運算60
2.3.1 無(wú)符號加法60
2.3.2 補碼加法62
2.3.3 補碼的非66
2.3.4 無(wú)符號乘法67
2.3.5 補碼乘法67
2.3.6 乘以常數70
2.3.7 除以2的冪71
2.3.8 關(guān)于整數運算的最后思考74
2.4 浮點(diǎn)數75
2.4.1 二進(jìn)制小數76
2.4.2 IEEE浮點(diǎn)表示78
2.4.3 數字示例79
2.4.4 舍入83
2.4.5 浮點(diǎn)運算85
2.4.6 C語(yǔ)言中的浮點(diǎn)數86
2.5 小結87
參考文獻說(shuō)明88
家庭作業(yè)88
練習題答案97
第3章 程序的機器級表示109
3.1 歷史觀(guān)點(diǎn)110
3.2 程序編碼113
3.2.1 機器級代碼113
3.2.2 代碼示例114
3.2.3 關(guān)于格式的注解117
3.3 數據格式119
3.4 訪(fǎng)問(wèn)信息119
3.4.1 操作數指示符121
3.4.2 數據傳送指令122
3.4.3 數據傳送示例125
3.4.4 壓入和彈出棧數據127
3.5 算術(shù)和邏輯操作128
3.5.1 加載有效地址129
3.5.2 一元和二元操作130
3.5.3 移位操作131
3.5.4 討論131
3.5.5 特殊的算術(shù)操作133
3.6 控制135
3.6.1 條件碼135
3.6.2 訪(fǎng)問(wèn)條件碼136
3.6.3 跳轉指令138
3.6.4 跳轉指令的編碼139
3.6.5 用條件控制來(lái)實(shí)現條件分支…141
3.6.6 用條件傳送來(lái)實(shí)現條件分支…145
3.6.7 循環(huán)149
3.6.8 switch語(yǔ)句159
3.7 過(guò)程164
3.7.1 運行時(shí)棧164
3.7.2 轉移控制165
3.7.3 數據傳送168
3.7.4 棧上的局部存儲170
3.7.5 寄存器中的局部存儲空間172
3.7.6 遞歸過(guò)程174
3.8 數組分配和訪(fǎng)問(wèn)176
3.8.1 基本原則176
3.8.2 指針運算177
3.8.3 嵌套的數組178
3.8.4 定長(cháng)數組179
3.8.5 變長(cháng)數組181
3.9 異質(zhì)的數據結構183
3.9.1 結構183
3.9.2 聯(lián)合186
3.9.3 數據對齊189
3.10 在機器級程序中將控制與數據結合起來(lái)192
3.10.1 理解指針192
3.10.2 應用:使用GDB調試器193
3.10.3 內存越界引用和緩沖區溢出194
3.10.4 對抗緩沖區溢出攻擊198
3.10.5 支持變長(cháng)棧幀201
3.11 浮點(diǎn)代碼204
3.11.1 浮點(diǎn)傳送和轉換操作205
3.11.2 過(guò)程中的浮點(diǎn)代碼209
3.11.3 浮點(diǎn)運算操作210
3.11.4 定義和使用浮點(diǎn)常數212
3.11.5 在浮點(diǎn)代碼中使用位級操作212
3.11.6 浮點(diǎn)比較操作213
3.11.7 對浮點(diǎn)代碼的觀(guān)察結論215
3.12 小結216
參考文獻說(shuō)明216
家庭作業(yè)216
練習題答案226
第4章 處理器體系結構243
4.1 Y86-64指令集體系結構245
4.1.1 程序員可見(jiàn)的狀態(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 邏輯設計和硬件控制語(yǔ)言HCL256
4.2.1 邏輯門(mén)257
4.2.2 組合電路和HCL布爾表達式257
4.2.3 字級的組合電路和HCL整數表達式258
4.2.4 集合關(guān)系261
4.2.5 存儲器和時(shí)鐘262
4.3 Y86-64的順序實(shí)現264
4.3.1 將處理組織成階段264
4.3.2 SEQ硬件結構272
4.3.3 SEQ的時(shí)序274
4.3.4 SEQ階段的實(shí)現277
4.4 流水線(xiàn)的通用原理282
4.4.1 計算流水線(xiàn)282
4.4.2 流水線(xiàn)操作的詳細說(shuō)明284
4.4.3 流水線(xiàn)的局限性284
4.4.4 帶反饋的流水線(xiàn)系統287
4.5 Y86-64的流水線(xiàn)實(shí)現288
4.5.1 SEQ+:重新安排計算階段288
4.5.2 插入流水線(xiàn)寄存器289
4.5.3 對信號進(jìn)行重新排列和標號292
4.5.4 預測下一個(gè)PC293
4.5.5 流水線(xiàn)冒險295
4.5.6 異常處理306
4.5.7 PIPE各階段的實(shí)現308
4.5.8 流水線(xiàn)控制邏輯314
4.5.9 性能分析322
4.5.10 未完成的工作323
4.6 小結325
參考文獻說(shuō)明326
家庭作業(yè)327
練習題答案331
第5章 優(yōu)化程序性能341
5.1 優(yōu)化編譯器的能力和局限性342
5.2 表示程序性能345
5.3 程序示例347
5.4 消除循環(huán)的低效率350
5.5 減少過(guò)程調用353
5.6 消除不必要的內存引用354
5.7 理解現代處理器357
5.7.1 整體操作357
5.7.2 功能單元的性能361
5.7.3 處理器操作的抽象模型362
5.8 循環(huán)展開(kāi)366
5.9 提高并行性369
5.9.1 多個(gè)累積變量370
5.9.2 重新結合變換373
5.10 優(yōu)化合并代碼的結果小結377
5.11 一些限制因素378
5.11.1 寄存器溢出378
5.11.2 分支預測和預測錯誤處罰379
5.12 理解內存性能382
5.12.1 加載的性能382
5.12.2 存儲的性能383
5.13 應用:性能提高技術(shù)387
5.14 確認和消除性能瓶頸388
5.14.1 程序剖析388
5.14.2 使用剖析程序來(lái)指導優(yōu)化390
5.15 小結392
參考文獻說(shuō)明393
家庭作業(yè)393
練習題答案395
第6章 存儲器層次結構399
6.1 存儲技術(shù)399
6.1.1 隨機訪(fǎng)問(wèn)存儲器400
6.1.2 磁盤(pán)存儲406
6.1.3 固態(tài)硬盤(pán)414
6.1.4 存儲技術(shù)趨勢415
6.2 局部性418
6.2.1 對程序數據引用的局部性418
6.2.2 取指令的局部性419
6.2.3 局部性小結420
6.3 存儲器層次結構421
6.3.1 存儲器層次結構中的緩存422
6.3.2 存儲器層次結構概念小結424
6.4 高速緩存存儲器425
6.4.1 通用的高速緩存存儲器組織結構425
6.4.2 直接映射高速緩存427
6.4.3 組相聯(lián)高速緩存433
6.4.4 全相聯(lián)高速緩存434
6.4.5 有關(guān)寫(xiě)的問(wèn)題437
6.4.6 一個(gè)真實(shí)的高速緩存層次結構的解剖438
6.4.7 高速緩存參數的性能影響439
6.5 編寫(xiě)高速緩存友好的代碼440
6.6 綜合:高速緩存對程序性能的影響444
6.6.1 存儲器山444
6.6.2 重新排列循環(huán)以提高空間局部性447
6.6.3 在程序中利用局部性450
6.7 小結450
參考文獻說(shuō)明451
家庭作業(yè)451
練習題答案459
第二部分
在系統上運行程序
第7章 鏈接464
7.1 編譯器驅動(dòng)程序465
7.2 靜態(tài)鏈接466
7.3 目標文件466
7.4 可重定位目標文件467
7.5 符號和符號表468
7.6 符號解析470
7.6.1 鏈接器如何解析多重定義的全局符號471
7.6.2 與靜態(tài)庫鏈接475
7.6.3 鏈接器如何使用靜態(tài)庫來(lái)解析引用477
7.7 重定位478
7.7.1 重定位條目479
7.7.2 重定位符號引用479
7.8 可執行目標文件483
7.9 加載可執行目標文件484
7.10 動(dòng)態(tài)鏈接共享庫485
7.11 從應用程序中加載和鏈接共享庫487
7.12 位置無(wú)關(guān)代碼489
7.13 庫打樁機制492
7.13.1 編譯時(shí)打樁492
7.13.2 鏈接時(shí)打樁492
7.13.3 運行時(shí)打樁494
7.14 處理目標文件的工具496
7.15 小結496
參考文獻說(shuō)明497
家庭作業(yè)497
練習題答案499
第8章 異??刂屏?01
8.1 異常502
8.1.1 異常處理503
8.1.2 異常的類(lèi)別504
8.1.3 Linux/x86-64系統中的異常505
8.2 進(jìn)程508
8.2.1 邏輯控制流508
8.2.2 并發(fā)流509
8.2.3 私有地址空間509
8.2.4 用戶(hù)模式和內核模式510
8.2.5 上下文切換511
8.3 系統調用錯誤處理512
8.4 進(jìn)程控制513
8.4.1 獲取進(jìn)程ID513
8.4.2 創(chuàng )建和終止進(jìn)程513
8.4.3 回收子進(jìn)程516
8.4.4 讓進(jìn)程休眠521
8.4.5 加載并運行程序521
8.4.6 利用fork和execve運行程序524
8.5 信號526
8.5.1 信號術(shù)語(yǔ)527
8.5.2 發(fā)送信號528
8.5.3 接收信號531
8.5.4 阻塞和解除阻塞信號532
8.5.5 編寫(xiě)信號處理程序533
8.5.6 同步流以避免討厭的并發(fā)錯誤540
8.5.7 顯式地等待信號543
8.6 非本地跳轉546
8.7 操作進(jìn)程的工具550
8.8 小結550
參考文獻說(shuō)明550
家庭作業(yè)550
練習題答案556
第9章 虛擬內存559
9.1 物理和虛擬尋址560
9.2 地址空間560
9.3 虛擬內存作為緩存的工具561
9.3.1 DRAM緩存的組織結構562
9.3.2 頁(yè)表562
9.3.3 頁(yè)命中563
9.3.4 缺頁(yè)564
9.3.5 分配頁(yè)面565
9.3.6 又是局部性救了我們565
9.4 虛擬內存作為內存管理的工具565
9.5 虛擬內存作為內存保護的工具567
9.6 地址翻譯567
9.6.1 結合高速緩存和虛擬內存570
9.6.2 利用TLB加速地址翻譯570
9.6.3 多級頁(yè)表571
9.6.4 綜合:端到端的地址翻譯573
9.7 案例研究:Intel Core i7/Linux內存系統576
9.7.1 Core i7地址翻譯576
9.7.2 Linux虛擬內存系統580
9.8 內存映射582
9.8.1 再看共享對象583
9.8.2 再看fork函數584
9.8.3 再看execve函數584
9.8.4 使用mmap函數的用戶(hù)級內存映射585
9.9 動(dòng)態(tài)內存分配587
9.9.1 malloc和free函數587
9.9.2 為什么要使用動(dòng)態(tài)內存分配589
9.9.3 分配器的要求和目標590
9.9.4 碎片591
9.9.5 實(shí)現問(wèn)題592
9.9.6 隱式空閑鏈表592
9.9.7 放置已分配的塊593
9.9.8 分割空閑塊594
9.9.9 獲取額外的堆內存594
9.9.10 合并空閑塊594
9.9.11 帶邊界標記的合并595
9.9.12 綜合:實(shí)現一個(gè)簡(jiǎn)單的分配器597
9.9.13 顯式空閑鏈表603
9.9.14 分離的空閑鏈表604
9.10 垃圾收集605
9.10.1 垃圾收集器的基本知識606
9.10.2 Mark&Sweep垃圾收集器607
9.10.3 C程序的保守Mark&Sweep608
9.11 C程序中常見(jiàn)的與內存有關(guān)的錯誤609
9.11.1 間接引用壞指針609
9.11.2 讀未初始化的內存609
9.11.3 允許棧緩沖區溢出610
9.11.4 假設指針和它們指向的對象是相同大小的610
9.11.5 造成錯位錯誤611
9.11.6 引用指針,而不是它所指向的對象611
9.11.7 誤解指針運算611
9.11.8 引用不存在的變量612
9.11.9 引用空閑堆塊中的數據612
9.11.10 引起內存泄漏613
9.12 小結613
參考文獻說(shuō)明613
家庭作業(yè)614
練習題答案617
第三部分
程序間的交互和通信
第10章 系統級I/O622 10.1 Unix I/O622
10.2 文件623
10.3 打開(kāi)和關(guān)閉文件624
10.4 讀和寫(xiě)文件625
10.5 用RIO包健壯地讀寫(xiě)626
10.5.1 RIO的無(wú)緩沖的輸入輸出函數627
10.5.2 RIO的帶緩沖的輸入函數627
10.6 讀取文件元數據632
10.7 讀取目錄內容633
10.8 共享文件634
10.9 I/O重定向637
10.10 標準I/O638
10.11 綜合:我該使用哪些I/O函數?638
10.12 小結640
參考文獻說(shuō)明640
家庭作業(yè)640
練習題答案641
第11章 網(wǎng)絡(luò )編程642
11.1 客戶(hù)端服務(wù)器編程模型642
11.2 網(wǎng)絡(luò )643
11.3 全球IP因特網(wǎng)646
11.3.1 IP地址647
11.3.2 因特網(wǎng)域名649
11.3.3 因特網(wǎng)連接651
11.4 套接字接口652
11.4.1 套接字地址結構653
11.4.2 socket函數654
11.4.3 connect函數654
11.4.4 bind函數654
11.4.5 listen函數655
11.4.6 accept函數655
11.4.7 主機和服務(wù)的轉換656
11.4.8 套接字接口的輔助函數660
11.4.9 echo客戶(hù)端和服務(wù)器的示例662
11.5 Web服務(wù)器665
11.5.1 Web基礎665
11.5.2 Web內容666
11.5.3 HTTP事務(wù)667
11.5.4 服務(wù)動(dòng)態(tài)內容669
11.6 綜合:TINY Web服務(wù)器671
11.7 小結678
參考文獻說(shuō)明678
家庭作業(yè)678
練習題答案679
第12章 并發(fā)編程681
12.1 基于進(jìn)程的并發(fā)編程682
12.2 基于I/O多路復用的并發(fā)編程684
12.3 基于線(xiàn)程的并發(fā)編程691
12.4 多線(xiàn)程程序中的共享變量696
12.5 用信號量同步線(xiàn)程698
12.6 使用線(xiàn)程提高并行性710
12.7 其他并發(fā)問(wèn)題716
12.8 小結722
參考文獻說(shuō)明723
家庭作業(yè)723
練習題答案726
附錄A 錯誤處理729
參考文獻733