發表於2024-12-13
程序員的自我修養:鏈接、裝載與庫 pdf epub mobi txt 電子書 下載
帶領你探索深層次的自己,走進新的程序世界!
眾多讀者學者讀過後愛不釋手,傾情推薦!
《程序員的自我修養:鏈接、裝載與庫》裝幀優雅精美,在京東取得不錯銷量!!
本書深入淺齣地對係統軟件的底層形成機製進行條分縷析,真正提升程序員的自我修養。
《程序員的自我修養:鏈接、裝載與庫》主要介紹係統軟件的運行機製和原理,涉及在Windows和Linux兩個係統平颱上,一個應用程序在編譯、鏈接和運行時刻所發生的各種事項,包括:代碼指令是如何保存的,庫文件如何與應用程序代碼靜態鏈接,應用程序如何被裝載到內存中並開始運行,動態鏈接如何實現,C/C++運行庫的工作原理,以及操作係統提供的係統服務是如何被調用的。每個技術專題都配備瞭大量圖、錶和代碼實例,力求將復雜的機製以簡潔的形式錶達齣來。本書最後還提供瞭一個小巧且跨平颱的C/C++運行庫MiniCRT,綜閤展示瞭與運行庫相關的各種技術。
《程序員的自我修養:鏈接、裝載與庫》對裝載、鏈接和庫進行瞭深入淺齣的剖析,並且輔以大量的例子和圖錶,可以作為計算機軟件專業和其他相關專業大學本科高年級學生深入學習係統軟件的參考書。同時,還可作為各行業從事軟件開發的工程師、研究人員以及其他對係統軟件實現機製和技術感興趣者的自學教材。
這是一本深人闡述鏈接、裝載和庫等問題的齣色圖書,讀來讓人愉悅,你從巾可以清晰地瞭解程序的前世今生,徹底理解敲人的代碼如何變成程序任係統中運行。通讀本書不管對於開發還是trouble shootin9都會很有幫助。建議每一位希望從事係統開發、或希望更實務地理解操作係統和編譯器、或不滿足於隻寫代碼的齣色程序員都擁有這樣一本書。
——鄒飛,趨勢科技(中國)研發中心專業軟件要程師
本書從大處著眼,小處著手,以通俗易懂的語言,深入淺齣地對係統軟件的底層形成機製進行條分縷析,正閤藥山禪師所謂“高高山頂立,深深海底行”。循著作者的思緒一路走來,有如醍醐灌頂。暢快淋灕。非常高興有預覽此書初稿的寶貴機會,我在瀏覽書稿和查核相關資料的過程中,學到瞭很多以前未知或知之不深的內容。
——馮亮,阿裏巴巴(中國)網絡技術有限公司運維部係統架構師
第1部分 簡介
第1章 溫故而知新
1.1 從HELLO WORLD 說起
1.2 萬變不離其宗
1.3 站得高,望得遠
1.4 操作係統做什麼
1.5 內存不夠怎麼辦
1.6 眾人拾柴火焰高
1.7 本章小結
第2部分 靜態鏈接
第2章 編譯和鏈接
2.1 被隱藏瞭的過程
2.2 編譯器做瞭什麼
2.3 鏈接器年齡比編譯器長
2.4 模塊拼裝——靜態鏈接
2.5 本章小結
第3章 目標文件裏有什麼
3.1 目標文件的格式
3.2 目標文件是什麼樣的
3.3 挖掘SIMPLESECTION.O
3.4 ELF 文件結構描述
3.5 鏈接的接口——符號
3.6 調試信息
3.7 本章小結
第4章 靜態鏈接
4.1 空間與地址分配
4.2 符號解析與重定位
4.3 COMMON 塊
4.4 C++相關問題
4.5 靜態庫鏈接
4.6 鏈接過程控製
4.7 BFD 庫
4.8 本章小結
第5章 WINDOWS PE/COFF
5.1 WINDOWS 的二進製文件格式PE/COFF 134
5.2 PE 的前身——COFF
5.3 鏈接指示信息
5.4 調試信息
5.5 大傢都有符號錶
5.6 WINDOWS 下的ELF——PE
5.7 本章小結
第3部分 裝載與動態鏈接
第6章 可執行文件的裝載與進程
6.1 進程虛擬地址空間
6.2 裝載的方式
6.3 從操作係統角度看可執行文件的裝載
6.4 進程虛存空間分布
6.5 LINUX 內核裝載ELF 過程簡介
6.6 WINDOWS PE 的裝載
6.7 本章小結
第7章 動態鏈接
7.1 為什麼要動態鏈接
7.2 簡單的動態鏈接例子
7.3 地址無關代碼
7.4 延遲綁定(PLT)
7.5 動態鏈接相關結構
7.6 動態鏈接的步驟和實現
7.7 顯式運行時鏈接
7.8 本章小結
第8章 LINUX 共享庫的組織
8.1 共享庫版本
8.2 符號版本
8.3 共享庫係統路徑
8.4 共享庫查找過程
8.5 環境變量
8.6 共享庫的創建和安裝
8.7 本章小結
第9章 WINDOWS 下的動態鏈接
9.1 DLL 簡介
9.2 符號導齣導入錶
9.3 DLL 優化
9.4 C++與動態鏈接
9.5 DLL HELL
9.6 本章小結
第4部分 庫與運行庫
第10章 內存
10.1 程序的內存布局
10.2 棧與調用慣例
10.3 堆與內存管理
10.4 本章小結
第11章 運行庫
11.1 入口函數和程序初始化
11.2 C/C++運行庫
11.3 運行庫與多綫程
11.4 C++全局構造與析構
11.5 FREAD 實現
11.6 本章小結
第12章 係統調用與API
12.1 係統調用介紹
12.2 係統調用原理
12.3 WINDOWS API
12.4 本章小結
第13章 運行庫實現
13.1 C 語言運行庫
13.2 如何使用MINI CRT
13.3 C++運行庫實現
13.4 如何使用MINI CRT++
13.5 本章小結
附錄A
A.1 字節序(BYTE ORDER)
A.2 ELF 常見段
A.3 常用開發工具命令行參考
索引
第1部分 簡介
第1章 溫故而知新
1.2 萬變不離其宗
計算機是個非常廣泛的概念,大到占用數層樓的用於科學計算的超級計算機,小到手機上的嵌入式芯片都可以被稱為計算機。雖然它們的外形、結構和性能都韆差萬彆,但至少它們都有“計算”這個概念。在本書裏麵,我們將計算機的範圍限定在最為流行、使用最廣泛的PC機,更具體地講是采用兼容x86指令集的32位CPU的個人計算機。原因很簡單:因為筆者手上目前隻有這種類型的計算機可供操作和實驗,不過相信90%以上的讀者也是,所以在這一點上我們很快能達成共識。其實選擇具體哪種平颱並不是最關鍵的,雖然各種平颱的軟硬件差彆很多,但是本質上它們的基本概念和工作原理都是一樣的,隻要我們能夠掌握一種平颱上的技術,那麼其他的平颱都是大同小異的,很輕鬆地可以舉一反三。所以我們相信,隻有你能夠深刻地理解x86平颱下的係統軟件背後的機理,當有一天你需要在MIPS指令集的嵌入式平颱上做開發,或者需要為64位的Windows或tinux開發應用程序的時候,你很快就能找到它們之間的相通之處。
撇開計算機硬件中紛繁復雜的各種設備、芯片及外圍接口等,站在軟件開發者的角度看,我們隻須抓住硬件的幾個關鍵部件。對於係統程序開發者來說,計算機多如牛毛的硬件設備中,有三個部件最為關鍵,它們分彆是中央處理器CPU、內存和I/O控製芯片,這三個部件幾乎就是計算機的核心瞭;對於普通應用程序開發者來說,他們似乎除瞭要關心CPU以外,其他的硬件細節基本不用關心,對於一些高級平颱的開發者來說(如Java、.NET或腳本語言開發者),連CPU都不需要關心,因為這些平颱為它們提供瞭一個通用的抽象的計算機,他們隻要關心這個象的計算機就可以瞭。
……
兩年前,甲子跟我提起,他在考慮寫一本講述計算機程序基本工作原理的書,由於代碼背後的許多細節現在難以找到完整而又實用的資料,因此,係統性地講述這些技術要素一定非常有意義。這是我非常感興趣的話題,因為最近幾年來,我每次給學生講課或作技術報告時,經常會提到程序背後的一些細節知識,而當有人請我推薦一些參考資料時,我很難想得齣有什麼恰當的參考書可供學習。我自己也曾想過要寫一點這方麵的書,隻是一直下不瞭決心做這件事情。甲子的提議讓我意識到,寫這樣一本書的機會來瞭。於是,我們認真規劃瞭書的選題。按我的建議,這應該是三捲本的書,每捲獨立,閤起來成一體係。第一捲是基礎篇,介紹程序的基本運行過程,即是您現在看到的這本書。其他兩捲還需要時日和機緣。
在過去兩年中,我曾經以“Inside Windows Programs”為題在多所高校作過報告,旨在介紹Windows程序背後的一些支撐技術。對於正在學習計算機或軟件專業的學生,或者正在從事軟件開發的工程師們,我認為理解這些支撐技術是很有必要的。試想,即使一個簡單的“Hello World!”程序,也依賴於背後的輸入輸齣庫(或流庫)及係統提供的模塊,這種依賴性已經成為現代軟件在操作係統環境下運行的一個必要條件。然而,有關這些支撐技術的係統性資料卻少而又少,雖然Internet上並不缺乏任何一方麵的細節信息,但是,能將程序的編譯和運行過程所涉及的各種技術全麵地串連起來介紹的,卻尚未有先例。
甲子曾經在2006年夏天跟我實習過兩個月,他幫我搭建瞭一個在Windows已有體係結構下將交換空間重定嚮到遠程機器物理內存的原型係統。完成這一係統並非易事,而且甲子事前並無Windows內核編程經驗,但是,他憑藉紮實的計算機係統軟件功底,成功地打通瞭從頁麵錯誤(page fault)異常例程到遠程機器內存管理器之間的數據通路。在這一段實習經曆中,我不僅看到瞭他駕馭代碼和係統的能力,也感受到他做事認真負責的態度。因此,當他提齣要寫一本介紹程序基礎的書時,我認為他是非常閤適的人選。考慮到寫書的艱巨性,他推薦石凡同學加入進來,這纔有瞭我們三個人的組閤。我原先擔心寫作的進度,畢竟寫這樣一本書需要大量的時間投入。幸運的是,在甲子和石凡的不懈努力下,這本書終於麵市瞭。
本書講解的內容,涉及在Windows和Linux兩個係統平颱上,一個應用程序在編譯、鏈接和運行時刻所發生的各種事項,包括:代碼指令是如何保存的,庫文件如何與應用程序代碼靜態鏈接,應用程序如何被裝載到內存中並開始運行,動態鏈接如何實現,C/C++運行庫如何工作,以及操作係統提供的係統服務是如何被調用的。每個技術專題都配備瞭大量圖示和代碼實例,力求將復雜的機製以簡潔的形式錶達齣來。本書最後還提供瞭一個小巧且跨平颱的C/C++運行庫MiniCRT,綜閤展示瞭與運行庫相關的各種技術。
關於寫作這本書的功勞,我不敢掠美。在創作之初,包括擬定提綱及甄選內容方麵,我跟甲子有過認真而細緻的討論;在寫作過程中,我對甲子和石凡的初稿提齣過一些建議,尤其在錶述方麵,同時我也協助他們與編輯進行瞭溝通和交流。對於正文的內容,我並無實質性的貢獻,但基於我對甲子和石凡兩位年輕人的瞭解,我相信他們自身的技術實踐功底,以及足夠的技術闡釋能力。我期待這本書能夠真正地提升程序員的自我修養,讓程序員總是生活在“知其然,更知其所以然”的代碼曼妙中。
最後,我要感謝這本書的四位編輯,他們是何艷、方舟、劉鐵鋒和陳元玉,謝謝他們為這本書付齣的努力。還要感謝博文視點團隊的負責人周筠女士,謝謝她給予兩位年輕作者的扶持和關愛。
潘愛民
2009年2月於北京微軟
七、作者序2
兩年前,我在浙江大學的一著名BBS的C++闆塊上擔任版主,而俞甲子則是闆上的資深版友(以及前版主)。那時候我對鏈接裝載、運行庫等內容比較感興趣,自己摸索著在博客上寫瞭一篇關於鏈接的入門文章,而這就是一切的開始。
我猜想俞甲子可能對寫這麼一本書早有想法,看到我的文章正好找到瞭同路人。他找到瞭我和潘愛民老師,我們一拍即閤,就開始瞭這長達兩年的寫作曆程。考慮到當時俞甲子已經在鏈接部分有瞭相當的積纍,因此我不得不放棄我最有興趣的一部分轉而在運行環境上做文章。我把glibc和msvcrt的源代碼翻瞭個底朝天,瞭解到瞭許多平時不可能接觸到的內幕和技術細節。事實上,這基本是一個現學現賣的過程,我一邊學習著新的知識,一邊把新知識組織整理寫成文字。讀者在看某些章節的時候,會發現這些章節的講解過程就是一個源代碼的挖掘過程,這實際上也就是我的學習過程。學習研究他人的代碼是枯燥而耗時的,我很高興能夠做這樣一個先行者,將我的經驗寫進書裏,讓讀者能夠避免重復勞動,直接獲得其中的經驗和關鍵技術。
本書所講的內容不是活躍在當今IT舞颱上的高新技術,也不是雄踞計算機某個領域的王牌霸主,而是默默服務於所有計算機應用的掃地僧。也許閱讀本書不能夠直接在平時學習工作中的生産力上得到體現,但瞭解計算機的颱前幕後會對讀者産生潛移默化的影響。當你的程序無法啓動的時候,你可能會在腦海裏多設想一種可能性;當你的代碼鏈接失敗的時候,你可能會更快地意識到問題的所在;當你的程序發生非法操作的時候,你可能不至於麵對微軟的錯誤報告毫無頭緒。有人總愛用“時效性”評價當今的IT技術。仿佛一項技術的生存期就隻有幾年。我不能說這樣的想法是錯誤的,如今的技術的確在飛速地更替和發展。但是本書所講的技術,大多是成型在十年前,乃至二十年前,它們是整個計算機行業技術的根本,也幾乎是現在所有計算機應用的基礎。在當今的計算機技術發生根本性變革之前,這些技術還將繼續存在並保持活力。
我很榮幸能夠有機會和讀者分享這些技術,但寫作水平有限(我在語文課上曆來不是個好學生),最終在文字和結構上頗有缺憾,隻能在這裏說一聲抱歉。在這裏要感謝我小學、初中和高中的語文老師,謝謝你們當初對我的教導,盡管最終可能辜負瞭你們的希望。感謝潘老師、博文視點的編輯及所有支持我們的朋友們,謝謝你們對我們的幫助。最後要感謝我的父母,沒有你們,我永遠不可能走到今天這一步。
石凡
2009年2月於杭州
八、作者序3
CPU體係結構、匯編、C語言(包括C++)和操作係統,永遠都是編程大師們的護身法寶,就如同少林寺的《易筋經》,是最為上乘的武功;學會瞭《易筋經》,你將無所不能,任你創造武功;學會瞭編程“易筋經”,大師們可以任意開發操作係統、編譯器,甚至是開發一種新的程序設計語言!
——佚名
念書的時候,作為標準的愛好技術的宅男,每天掃一遍各大高校BBS的技術版麵,基本好比一日三餐一樣平常。我對計算機技術方麵的口味很雜,從匯編版到C++到Linux內核開發、Linux應用開發、遊戲開發、網絡、編程語言、體係結構、移動開發、開源閉源我都會參上一腳。
我始終認為技術優劣取決於需求,與很多持有“編程語言血統論”的程序開發者不同,我不認為C++或Java本身有什麼直接可比性,或者OOP與函數式編程誰優誰劣,我始終堅持認為作為開發者,MOP(Market/Money Oriented Programming)纔是唯一不變的編程範式。於是我往往不參與那些技術、平颱、語言教派之間的宗教戰爭,這種論戰基本上每周都會有,我很佩服論戰各方見多識廣、旁徵博引、高屋建瓴的論斷,但我往往隻是灌灌水調節一下思緒。相反,我很關注一些與語言、平颱等相對獨立的基本的係統概念方麵的問題,這些問題比較具體,也比較實用,比如:
為什麼程序是從main開始執行?
“malloc分配的空間是連續的嗎?”
“PE/ELF文件裏麵存的是什麼?”
“我想寫一個不需要操作係統可以直接在硬件上跑的程序該怎麼做?”
“目標文件是什麼?鏈接又是什麼?”
“為什麼這段程序鏈接時報錯?”
“句柄到底是什麼東西?”
這些問題看似很簡單但實際上有很多值得深入挖掘的地方,比如第一個問題圍繞著main函數執行前後可以延伸齣一大堆問題:程序入口、運行庫初始化、全局/靜態對象構造析構、靜態和動態鏈接時程序的初始化和裝載等。我們把這些問題歸結起來,發現主要是三個很大的而且連貫的主題,那就是“鏈接、裝載和庫”。
事實上,現在市麵上和網絡上能找到的計算機技術方麵的書籍和資料中,什麼都很齊全,唯獨關於這三個主題的討論十分稀缺,即使能找到一些也是猶如殘缺的典籍,不僅不完整而且很多已經過時瞭。關於現在通用的Windows和Linux平颱的鏈接、裝載及PE/ELF文件的詳細分析,實在很少見。這個領域中,最為完整、也最為權威的莫過於John R. Levine的《Linkers & Loaders》,這本書我也前前後後通讀瞭好幾遍,雖然它對鏈接和裝載方麵的描述較為完整,但是過於理論化,對於實際的係統機製描述則過於簡略。
我始終認為對於一個問題比較好的描述方式,是由一個很小很簡單的問題或示例入手,層層剝開深入挖掘,不僅探究每個機製“怎麼做”,而且要理解它們“為什麼這樣做”,力求深入淺齣、圖文並茂,盡力把每一步細節都呈現給讀者。這是我一貫的想法,也是我們在本書中努力試圖達到的效果。
第一次有想寫這樣一本書的念頭是在2006年底,當時我正在念研一,想起未來還有一年多漫長而又相對空閑的研究生生涯,覺得寫一本這樣的書大概是比較好的“消遣活動”。於是我第一時間想到瞭在微軟研究院實習時的導師潘愛民老師,潘老師在寫作技術書籍方麵有很深的功底和豐富的經驗。我把想法告訴潘老師以後,他十分支持,於是我又找到瞭當時剛好保送研究生、時間上也相對充裕的石凡,我們三個都對這個選題十分感興趣,可謂一拍即閤。
當時也沒多想,以為寫書大概也就跟BBS發帖連載差不多吧。一旦寫起來纔發現自己完全輕視瞭寫書的工作量。書中的每一個章節、每一個小段、每一個例子甚至每一個用詞有時候都要斟酌很久,生怕用得不恰當誤導瞭讀者。“誤人子弟”這四個字罪名可不輕,大有推齣午門斬首五遍以儆效尤之過。寫書的時間的確很倉促,雖然我們都是在讀研時寫的,按理說相對於已經工作的作者來講,已經是有很多閑餘的時間瞭,但還是經常手忙腳亂。想到以前看書看到作者寫的序裏,經常使用“時間倉促,水平有限”的話,推想作者不過是齣於謙虛不免要客套一下。現在輪到自己寫序瞭,終於感覺到瞭這八個字的分量。即使到現在已近完稿,我們還是心裏十分忐忑,因為還有不少地方的確寫得不夠完善。也聽到瞭很多第一批讀者的反饋意見,很多建議都正中這本書的軟肋,我們也根據大傢的意見又一次進行瞭修改,這已經是反反復復的第N次修訂瞭。
這本書前前後後花瞭兩年多的時間一直沒有完稿,由於截稿時間快到瞭,我們纔終於定稿,因為實在沒有辦法做到完美,隻能嚮無限接近完美努力。最後,我們在“著”和“編著”之間猶豫瞭很久,想到本書凝聚瞭我們很多的心血,還是誠惶誠恐地寫上瞭“著”字,權當給自己壯膽瞭。我們也相信,本書雖然沒做到完美,但是它一定會給你帶來一些你以前想看、想瞭解而又找不到的東西。或者以前在編程過程中睏惑瞭你很久,但始終沒有找到解釋的問題,當在本書中終於找到答案且大呼“原來如此!”時,我們也就很欣慰瞭!
關於本書的書名筆者們也討論瞭很久,徵詢過很多意見,最終還是決定用“程序員的自我修養”作為書名,將“鏈接、裝載與庫”作為副標題。書名源自於俄羅斯的演員斯坦尼斯拉夫斯基創作的《演員的自我修養》,作者為瞭寫這本書前前後後修改瞭三十年之久,臨終前纔同意不再修改,拿去齣版。使用這個書名一方麵是本書的內容的確不是介紹一門新的編程語言或展示一些實用的編程技術,而是介紹程序運行背後的機製和由來,可以看作是程序員的一種“修養”;另一方麵是嚮斯坦尼斯拉夫斯基緻敬,嚮他對作品精益求精的精神緻敬。
在本書的創作過程中,很多人對我們的支持和幫助難以言錶。這裏我要感謝博文視點的幾位編輯何艷、方舟、劉鐵鋒和陳元玉等,他們為本書付齣瞭很多心血;特彆要感謝博文視點的周筠老師,這本書能夠麵世離不開她的支持和努力。另外也要感謝浙江大學的張曉龍博士,他為本書提齣瞭很多建議,並且貢獻瞭“DLL HELL”一節。
俞甲子
2009年2月於杭州
此用戶未填寫評價內容
評分內容很不錯,簡明易懂。
評分一直想讀的一本書
評分寫的挺好的,搞底層的可以買來看看,推薦購買。。
評分書很實惠,價格活動買的很給力,包裝很專業!相當有難度
評分書偏厚,對於動態鏈接部分,講錯的不夠清楚,可參考《深入理解計算機係統》第8章。
評分還不錯,講的很清楚。
評分很好,看過電子版,買實體書
評分《程序員修煉之道:從小工到專傢》由一係列獨立的部分組成,涵蓋的主題從個人責任、職業發展,直到用於使代碼保持靈活、並且易於改編和復用的各種架構技術,利用許多富有娛樂性的奇聞軼事、有思想性的例子及有趣的類比,全麵闡釋瞭軟件開發的許多不同方麵的較佳實踐和重大陷阱。
程序員的自我修養:鏈接、裝載與庫 pdf epub mobi txt 電子書 下載