-- 會員 / 註冊 --  
 帳號:
 密碼:
  | 註冊 | 忘記密碼
3/26 新書到! 3/19 新書到! 3/14 新書到! 12/12 新書到!
購書流程Q & A站務留言版客服信箱
3ds MaxMayaRhinoAfter EffectsSketchUpZBrushPainterUnity
PhotoShopAutoCadMasterCamSolidWorksCreoUGRevitNuke
C#CC++Java遊戲程式Linux嵌入式PLCFPGAMatlab
駭客資料庫搜索引擎影像處理FluentVR+ARANSYS深度學習
單晶片AVROpenGLArduinoRaspberry Pi電路設計CadenceProtel
HadoopPythonStm32CortexLabview手機程式AndroidiPhone
可查書名,作者,ISBN,3dwoo書號
詳細書籍分類

高級C/C++編譯技術

( 簡體 字)
作者:〔美〕 米蘭·斯特瓦諾維奇(Milan Stevanovic) 著類別:1. -> 程式設計 -> 組合語言/編譯原理 -> 編譯原理
   2. -> 程式設計 -> C -> C
   3. -> 程式設計 -> C++ -> C++
譯者:
出版社:機械工業出版社高級C/C++編譯技術 3dWoo書號: 41590
詢問書籍請說出此書號!

缺書
NT售價: 345

出版日:5/1/2015
頁數:266
光碟數:0
站長推薦:
印刷:黑白印刷語系: ( 簡體 版 )
加入購物車 加到我的最愛
(請先登入會員)
ISBN:9787111496182
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證)
作者序:

譯者序:

前言:

當長的時間才認識到,計算機編程藝術與烹飪藝術之間存在著驚人的相似性。

說到烹飪和編程的比較,我的腦海中首先浮現出來的是烹飪專家和程序員的工作目標非常相似:都是為了滿足特定對象的需求。對一個廚師來說,他的服務對象是食客,他需要使用大量的食材,一方面滿足人們的溫飽與營養需求,另一方面則要讓人們享受到美食帶來的快樂。而對一個程序員來說,其服務對象是微處理器,程序員使用大量不同的程序來為其提供代碼,不僅要讓微處理器產生有意義的動作,還需要以最優的形式將代碼交付給微處

理器。

雖說這種對比看起來有些牽強而且過于簡單,但我們會在本書中列出一些更加合適和更具說服力的對比。

介紹烹飪方法的食譜的數量繁多。幾乎所有的流行雜志都會開設專欄來介紹形形色色的美食和烹飪方法,無論是快餐式的食譜還是精致復雜的食譜、注重食材的食譜還是注重搭配稀有食材的食譜,你都能夠找到。

但如果你希望自己成為烹飪大師,就會發現很難找到可供參考的資料,比如食品行業經營(批量生產、飯店或餐飲企業的經營)、食品生產的供需管理、選料和食材保鮮方面的指南或資料。很顯然,這就是業余烹飪愛好者和專業食品企業之間的區別。

這種情況與程序設計其實非常相似。

我們可以輕松地從成千上萬的書籍、雜志、文章、網絡論壇和博客中搜集到編程語言方面的各類信息,無論是入門教程,還是“谷歌編程面試指南”這樣的技巧。

但是,這類主題所涵蓋的內容只能滿足成為專業軟件工程師一半的要求。我們不能一直沉浸在因程序實際執行(且執行正確)而帶來的喜悅當中,而需要著重考慮接下來的問題:如何組織代碼結構以便將來修改、如何從功能模塊中提取出可重用代碼,以及如何讓程序能夠適應不同的運行環境(無論是不同的人類語言和字符,還是在不同的操作系統環境中

運行)。

相較于其他編程主題來說,人們很少討論這類問題。時至今日,這類問題變成了只有計算機科學專業人士(絕大多數軟件架構師和構建工程師)和大學課堂上講解編譯器、鏈接器設計時,才會了解的“黑科技”。

由于Linux市場份額增加,而且越來越多的人都將Linux作為其編程環境,這促使開發人員開始關注Linux編程的相關問題。與在一些封裝良好的平臺(在Windows和Mac平臺上利用IDE和SDK將程序員從一些特定的編程細節問題中解放出來)開發軟件的開發人員不同,Linux開發人員在日常工作中需要將來自不同項目且編碼風格迥異的代碼組合起來,這需要開發人員充分理解編譯器、鏈接器的內部工作機制和程序裝載機制,以及不同庫的設計細節和使用方法。

本書將許多零碎的知識點進行匯總,并討論其中那些有價值的內容,這些內容則通過一系列精心設計的簡單示例進行驗證。需要注意的是,本書的作者并非計算機科學科班出身。20世紀90年代末至今的數字革命中,作者作為電氣工程師供職于硅谷的一家多媒體行業高新技術企業,并因此掌握了相關領域的知識。希望本書的主題和內容能夠讓更多讀者受益。

讀者對象

作為一名軟件設計實踐顧問(雖然很忙,但我還是非常自豪的),我經常會與不同專業背景和資歷的人群溝通。我在工作周中需要經常在不同的辦公環境中工作,因此接觸了許多開發人員(絕大多數來自硅谷),這也讓我更加了解了本書的受眾群體。其中包括以下幾類人群。

第一類受眾群體是來自不同工程領域的C/C++開發人員(電氣工程、機械、機器人技術和系統控制、航天、物理和化學等領域),這類人需要在日常工作中通過編程來解決問題。對缺乏正規計算機科學課程和理論教學的人來說,本書所提供的資料彌足珍貴。

第二類受眾群體是具有計算機科學教育背景的初級程序員。本書能夠幫助大家將主修課程中學到的知識具體化,并注重實踐。將第12章∼第14章的內容作為手冊查閱,對資深工程師而言,也會有所受益。

第三類受眾群體是操作系統集成和定制的愛好者。理解二進制文件及其內部工作機制將有助于在解決問題的過程中掃除障礙。

關于本書

我最初并沒有計劃去寫這么一本書,甚至都沒有打算寫一本計算機科學領域的書。(我有可能會去編寫信號處理或程序設計藝術方面的書,但編寫計算機科學方面的書?不……)

在職業生涯中,我經常處理當時我認為別人已經解決好的一些問題,而實際上這些問題并沒有得到根本性解決,這是我寫作此書的唯一原因。

很久以前,我決定成為一名從事高科技領域的“刺客”,將許多看似平靜且體面的高科技公司從“恐怖分子”——復雜多媒體設計問題和大量嚴重缺陷所造成的破壞中解救出來。選擇這樣一個職業的結果就是,我并沒有多少時間處理自己的生活,比如說孩子們想吃雞肉而不是豌豆,我很難滿足他們的這些需求。雖然我更傾向于使用傅里葉變換算法、小波、Z變換、FIR和IIR濾波器、倍頻程、半音程、插值和抽取算法來解決問題(與C/C++編程一起使用),但我還是要解決那些我并不喜歡解決的問題。總要有人去做這些事情吧。

出乎意料的是,在搜索一些非常簡單明了的問題的答案時,我只能找到一些散亂的網絡文章,而且絕大多數都只是泛泛而談。我很耐心地把這些散亂的內容組織到一起,不僅完成了我手頭的設計任務,而且學習總結了很多資料。

在一個天朗氣清的日子里,我開始整理設計筆記(記錄我工作中經常遇到的一些問題和解決方案)。但在整理工作完成的時候,這些筆記看起來就像……嗯……就像一本書——就是這本書。

不管怎么說……

就目前就業市場的情況而言,我認為(自2005年左右開始)熟悉C/C++語言的復雜性,甚至是算法、數據結構和設計模式,對于找到一份好工作都是遠遠不夠的。

在開源盛行的今天,專業開發人員在日常工作中所編寫的代碼越來越少,取而代之的是將現有代碼集成到項目中。這不僅要求開發人員能夠讀懂其他人編寫的代碼(使用不同的代碼風格和實踐),還需要了解如何才能以最好的方式將現有的包(絕大多數以二進制文件(庫)和導出頭文件的形式提供)集成到代碼中。

我希望本書能夠兼具教學(對亟須這些知識的讀者而言)和快速查詢的功能(對分析C/C++二進制文件相關工作的工程師而言)。

為何采用Linux進行演示?

選擇Linux并非我個人的偏好。實際上了解我的人都知道,我過去是多么喜歡使用Windows作為開發環境(原本這是我首選的設計平臺),原因是Windows平臺具有編寫良好的文檔、完善的支持和符合規范的認證組件。我設計過許多專業化軟件(曾為Palm公司設計開發了Windows Mobile平臺的GraphEdit,其中包含了許多最為復雜的功能,隨后又開發了多個媒體格式和DSP分析軟件),在當時我對Windows的技術了如指掌,并感嘆Windows相關技術所帶來的改變。

與此同時, Linux的時代到來了。有關Linux的技術隨處可見,而對開發人員來說,也必須順應這種趨勢去學習和使用它。

Linux軟件開發環境具有開放、透明和簡單明了的特點。在Linux中,我們可以對每個程序設計階段進行控制。同時,Linux提供了完善的文檔,再加上網絡上提供的資源,就可以輕松地使用GNU工具鏈。

實際上,由于Linux C/C++開發經驗可以直接適用于Mac OS平臺的底層開發,因此我最終決定選用Linux/GNU作為本書所涵蓋的主要開發環境。

別急!Linux與GNU完全是兩回事!

實際上,Linux是內核,而GNU中包含了Linux內核之上的所有軟件。除了GNU編譯器(可以在其他操作系統上使用,比如Windows上的MinGW)以外,在絕大多數情況下,GNU與Linux的關系其實非常緊密。為了簡單起見,同時為了符合一般開發人員對開發場景的認識,特別是為了將Linux與Windows進行對比,本書將GNU與Linux作為一個整體,簡稱為“Linux”。

章節概覽

第2章∼第5章講解的內容主要為后續內容做鋪墊。擁有計算機科學背景的讀者可以快速閱讀這些章節(幸運的是,這些章節的內容并不長)。實際上,任何計算機科學方面的教科書都會對這些內容進行類似介紹,而且內容會更為詳細。我個人推薦由Bryant和O’Hallaron編寫的《深入理解計算機系統》(《Computer Systems—A Programmer’s Perspective》)一書,原因是本書對很多主題都進行了非常有條理的梳理和總結。

第6章∼第11章是本書的核心章節。為求整體內容簡潔明了,我花費了相當大的精力,并嘗試使用一些日常生活中常見事物的文字和圖片,來闡述那些最為重要的核心概念。如果你不是計算機科學科班出身,那么有必要先理解這些內容。其實這些章節是本書主題的要點。

第12章∼第14章主要概括了一些實踐方面的內容,便于讀者快速查找相關的概念。這些章節針對一些特定平臺的二進制文件分析工具進行了總結,然后在實踐部分涵蓋了完成獨立任務的方法。
內容簡介:

從多個角度全面、系統地講解多任務操作系統中編譯、鏈接、裝載與庫的內幕和技術細節,為深入理解和掌握系統底層技術提供詳實參考和實踐指南。與純粹講解理論與技術細節的書不同,本書一方面對基本的理論進行了闡述,另一方面則聚焦于C/C++使用靜態庫和動態庫的一些注意事項,并舉例說明如何解決實際的鏈接與裝載問題。此外,本書盡量使用通俗易懂的語言來闡述這些知識,并補充了大量示例,避免讓讀者整天糾結于枯燥的理論。
本書共14章,其中第1章至第4章對多任務操作系統、程序生命周期以及代碼重用等重要概念進行介紹,為后續內容做鋪墊;第5章介紹靜態庫的使用方法及其設計技巧;第6章至第11章介紹動態庫的相關概念,包括不同平臺中動態庫的技術細節,比如庫文件定位、引用解析與符號處理等,以及一些動態庫設計的基本方法與原則和不同平臺下應當注意的設計細節;第12章至第14章主要給出一些實踐方面的總結,便于讀者快速查找相關的概念,而且還總結了一些特定平臺的二進制文件分析工具。
學習如何編寫C/C++代碼僅僅是個開始。如果你希望從事系統底層開發,或想深入理解操作系統、編譯器及它們之間內在的關聯,成為“編程專家”,那么就必須對編譯器生成的二進制文件(目標文件、靜態庫、動態庫和可執行文件)的作用和結構進行充分的了解。開源已經在許多方面從根本上改變了軟件的原有面貌,越來越多的系統開始采用或集成開源代碼,因此對每位開發人員來說,學習和理解這些底層技術也變得十分重要。
本書深入淺出地講解了構建過程(編譯、鏈接)中的各種細節,從多個角度展示了程序與庫文件或代碼的集成方法,提出了面向代碼復用和系統集成的軟件架構設計方法,以及系統開發過程中疑難問題的解決方案。同時,本書也是一本C/C++二進制文件方面的軟件工程指南,涵蓋中級和專家程序員所需的各方面內容和信息。

通過閱讀本書,你將學到:
構建過程(編譯和鏈接)與裝載過程的內部原理
靜態庫、動態庫和可執行文件的內部工作機制
面向代碼復用和系統集成的軟件架構設計方法
編譯、鏈接與運行時出現問題的排查技巧
在Linux和Windows平臺下利用二進制文件分析工具進行分析
目錄:

譯者序

前言

第1章 多任務操作系統基礎 1

1.1 一些有用的抽象概念 1

1.2 存儲器層次結構與緩存策略 2

1.3 虛擬內存 3

1.4 虛擬地址 5

1.5 進程的內存劃分方案 5

1.6 二進制文件、編譯器、鏈接器與裝載器的作用 6

1.7 小結 7

第2章 程序生命周期階段基礎 8

2.1 基本假設 8

2.2 編寫代碼 9

2.3 編譯階段 11

2.3.1 基本概念 11

2.3.2 相關概念 11

2.3.3 編譯的各個階段 12

2.3.4 目標文件屬性 23

2.3.5 編譯過程的局限性 24

2.4 鏈接 26

2.4.1 鏈接階段 26

2.4.2 鏈接器視角 31

2.5 可執行文件屬性 33

2.5.1 各種節的類型 34

2.5.2 各種符號類型 36

第3章 加載程序執行階段 37

3.1 shell的重要性 37

3.2 內核的作用 39

3.3 裝載器的作用 39

3.3.1 裝載器視角下的二進制文件(節與段) 39

3.3.2 程序加載階段 40

3.4 程序執行入口點 43

3.4.1 裝載器查找入口點 43

3.4.2 _start()函數的作用 43

3.4.3 __libc_start_main()函數的作用 44

3.4.4 棧和調用慣例 44

第4章 重用概念的作用 46

4.1 靜態庫 46

4.2 動態庫 48

4.2.1 動態庫和共享庫 49

4.2.2 動態鏈接詳解 51

4.2.3 Windows平臺中動態鏈接的特點 54

4.2.4 動態庫的特點 56

4.2.5 應用程序二進制接口(ABI) 56

4.3 靜態庫和動態庫對比 57

4.3.1 導入選擇條件的差異 57

4.3.2 部署難題 59

4.4 一些有用的類比 61

4.5 結論:二進制復用概念所產生的影響 63

第5章 使用靜態庫 64

5.1 創建靜態庫 64

5.1.1 創建Linux靜態庫 64

5.1.2 創建Windows靜態庫 65

5.2 使用靜態庫 65

5.3 靜態庫設計技巧 66

5.3.1 丟失符號可見性和唯一性的可能性 66

5.3.2 靜態庫使用禁忌 67

5.3.3 靜態庫鏈接的具體規則 68

5.3.4 將靜態庫轉換成動態庫 68

5.3.5 靜態庫在64位Linux平臺上的問題 68

第6章 設計動態鏈接庫:基礎篇 70

6.1 創建動態鏈接庫 70

6.1.1 在Linux中創建動態庫 70

6.1.2 在Windows中創建動態鏈接庫 72

6.2 設計動態庫 75

6.2.1 設計二進制接口 75

6.2.2 設計應用程序的二進制接口 79

6.2.3 控制動態庫符號的可見性 82

6.2.4 完成鏈接需要滿足的條件 94

6.3 動態鏈接模式 94

6.3.1 加載時動態鏈接 95

6.3.2 運行時動態鏈接 95

6.3.3 比較兩種動態鏈接模式 98

第7章 定位庫文件 99

7.1 典型用例場景 99

7.1.1 開發用例場景 99

7.1.2 用戶運行時用例場景 100

7.2 構建過程中庫文件的定位規則 101

7.2.1 Linux平臺構建過程中的庫文件定位規則 101

7.2.2 Windows構建過程中的庫文件定位規則 105

7.3 運行時動態庫文件的定位規則 109

7.3.1 Linux運行時動態庫文件的定位規則 110

7.3.2 Windows運行時動態庫文件的定位規則 114

7.4 示例:Linux構建時與運行時的庫文件定位 115

第8章 動態庫的設計:進階篇 119

8.1 解析內存地址的必要性 119

8.2 引用解析中的常見問題 120

8.3 地址轉換引發的問題 122

8.3.1 情景1:客戶二進制程序需要知道動態庫符號地址 122

8.3.2 情景2:被裝載的庫不需要知道其自身符號地址 123

8.4 鏈接器-裝載器協作 124

8.4.1 總體策略 125

8.4.2 具體技術 126

8.4.3 鏈接器重定位提示概述 127

8.5 鏈接器-裝載器協作實現技術 128

8.5.1 裝載時重定位(LTR) 129

8.5.2 位置無關代碼(PIC) 129

第9章 動態鏈接時的重復符號處理 134

9.1 重復的符號定義 134

9.2 重復符號的默認處理 137

9.3 在動態庫鏈接過程中處理重復符號 140

9.3.1 處理重復符號問題的一般策略 142

9.3.2 鏈接器解析動態庫重復符號的模糊算法準則 143

9.4 特定重復名稱案例分析 144

9.4.1 案例1:客戶二進制文件符號與動態庫ABI函數沖突 144

9.4.2 案例2:不同動態庫的ABI符號沖突 147

9.4.3 案例3:動態庫ABI符號和另一個動態庫局部符號沖突 151

9.4.4 案例4:兩個未導出的動態庫符號沖突 153

9.5 小提示:鏈接并不提供任何類型的命名空間繼承 161

第10章 動態庫的版本控制 162

10.1 主次版本號與向后兼容性 162

10.1.1 主版本號變更 162

10.1.2 次版本號變更 163

10.1.3 修訂版本號 163

10.2 Linux動態庫版本控制方案 163

10.2.1 基于soname的版本控制方案 163

10.2.2 基于符號的版本控制方案 169

10.3 Windows動態庫版本控制 190

10.3.1 DLL版本信息 191

10.3.2 指定DLL版本信息 192

10.3.3 查詢并獲取DLL版本信息 193

第11章 動態庫:其他主題 202

11.1 插件 202

11.1.1 導出規則 203

11.1.2 一些流行的插件架構 204

11.2 提示和技巧 204

11.2.1 使用動態庫的實際意義 204

11.2.2 其他主題 205

第12章 Linux工具集 211

12.1 快速查看工具 211

12.1.1 file實用程序 211

12.1.2 size實用程序 212

12.2 詳細信息分析工具 212

12.2.1 ldd 212

12.2.2 nm 214

12.2.3 objdump 215

12.2.4 readelf 223

12.3 部署階段工具 229

12.3.1 chrpath 229

12.3.2 patchelf 230

12.3.3 strip 231

12.3.4 ldconfig 231

12.4 運行時分析工具 232

12.4.1 strace 232

12.4.2 addr2line 233

12.4.3 gdb(GNU調試器) 233

12.5 靜態庫工具 234

第13章 平臺實踐 238

13.1 鏈接過程調試 238

13.2 確定二進制文件類型 239

13.3 確定二進制文件入口點 240

13.3.1 獲取可執行文件入口點 240

13.3.2 獲取動態庫入口點 240

13.4 列出符號信息 241

13.5 查看節的信息 242

13.5.1 列出所有節的信息 242

13.5.2 查看節的信息 242

13.6 查看段的信息 243

13.7 反匯編代碼 244

13.7.1 反匯編二進制文件 244

13.7.2 反匯編正在運行的進程 244

13.8 判斷是否為調試構建 244

13.9 查看加載時依賴項 245

13.10 查看裝載器可以找到的庫文件 245

13.11 查看運行時動態鏈接的庫文件 245

13.11.1 strace實用程序 245

13.11.2 LD_DEBUG環境變量 246

13.11.3 /proc//maps文件 246

13.11.4 lsof實用程序 247

13.11.5 通過編程方式查看 248

13.12 創建和維護靜態庫 251

第14章 Windows工具集 252

14.1 庫管理器(lib.exe) 252

14.1.1 使用lib.exe處理靜態庫 253

14.1.2 使用lib.exe處理動態庫(導入庫生成工具) 257

14.2 dumpbin實用程序 258

14.2.1 確定二進制文件類型 258

14.2.2 查看DLL的導出符號 258

14.2.3 查看節的信息 259

14.2.4 反匯編代碼 262

14.2.5 確定是否使用了調試模式構建 263

14.2.6 查看加載時依賴項 265

14.3 Dependency Walker工具 265
序: