《深入理解计算机系统》第七章读书笔记
生活随笔
收集整理的這篇文章主要介紹了
《深入理解计算机系统》第七章读书笔记
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
《深入理解計(jì)算機(jī)系統(tǒng)》第七章讀書筆記
第七章:連接
連接
1.連接:將各種代碼和數(shù)據(jù)部分收集起來并組合成為一個(gè)單一文件的過程。這個(gè)文件可被加載或拷貝到存儲(chǔ)器并執(zhí)行。 2.連接可以執(zhí)行于編譯時(shí),也就是在源代碼被翻譯成機(jī)器代碼也可以執(zhí)行于加載時(shí),也就是程序被加載器加載到存儲(chǔ)器并執(zhí)行時(shí)執(zhí)行于運(yùn)行時(shí),有應(yīng)用程序來執(zhí)行。 3.連接是由鏈接器的程序自動(dòng)執(zhí)行的。 4.連接使分離編譯成為可能。
PS:X86-64系統(tǒng)上用gcc -m32產(chǎn)生32位代碼
7.1編譯器驅(qū)動(dòng)程序
1.大部分編譯系統(tǒng)提供編譯驅(qū)動(dòng)程序:代表用戶在需要時(shí)調(diào)用語言預(yù)處理器、編譯器、匯編器和鏈接器。(1)C預(yù)處理器:源程序main.c->ASCII碼中間文件main.i(2)C編譯器:main.i->ASCII碼匯編語言文件main.s(3)C匯編器:main.s->可重定位目標(biāo)文件 2.運(yùn)行鏈接器程序ld,將各種.o文件以及必要的系統(tǒng)目標(biāo)文件組合起來,創(chuàng)建可執(zhí)行文件。 3.運(yùn)行可執(zhí)行文件:./可執(zhí)行文件名字 4.外殼調(diào)用操作系統(tǒng)中加載器函數(shù),拷貝可執(zhí)行文件中的代碼和數(shù)據(jù)到存儲(chǔ)器,將控制轉(zhuǎn)移到這個(gè)程序的開頭
7.2靜態(tài)鏈接
ld靜態(tài)鏈接器:
1.以一組可重定位目標(biāo)文件和命令行參數(shù)作為輸入,生成一個(gè)完全鏈接的可以加載和運(yùn)行的可執(zhí)行目標(biāo)文件作為輸出。 2.輸入的可重定位的目標(biāo)文件由各種不同的代碼和數(shù)據(jù)節(jié)組成 3.指令在一個(gè)節(jié)中,初始化的全局變量在另一個(gè)節(jié)中,而未初始化的變量又在另外一個(gè)節(jié)中。為了構(gòu)造可執(zhí)行文件,鏈接器的任務(wù):符號(hào)解析,重定位
7.3目標(biāo)文件
目標(biāo)文件三種形式:可重定位目標(biāo)文件,可執(zhí)行目標(biāo)文件,共享目標(biāo)文件。目標(biāo)文件格式:Linux——可執(zhí)行可連接(ELF格式)Windows——可移植可執(zhí)行格式(PE)
7.4可重定位目標(biāo)文件
ELF可重定位目標(biāo)文件包含下面幾個(gè)節(jié): .test已編譯程序的機(jī)器代碼。 .rodata只讀數(shù)據(jù) .data已初始化的全局C變量 .bss未初始化的全局C變量。.symtab:一個(gè)符號(hào)表,存放在程序中定義和引用的函數(shù)和全局變量的信息
7.5符號(hào)和符號(hào)表
每個(gè)可重定位目標(biāo)模塊m都有一個(gè)符號(hào)表,包含m所定義和引用的符號(hào)的信息。 在鏈接器的上下文中,三種不同的符號(hào): 1.有m定義并能被其他模塊引用的全局符號(hào)。全局鏈接器對(duì)應(yīng)于非靜態(tài)的C函數(shù)以及被定義為Cstatic 屬性的全局變量。 2.有其他模塊定義并被模塊m以引用的全局符號(hào)——外部符號(hào),對(duì)應(yīng)于定義在其他模塊中的C函數(shù)和變量 3.只被模塊m定義和引用的本地符號(hào)。
?1.任何聲明帶有static屬性的全局變量或者函數(shù)都是模塊私有的。
?2.任河聲明為不帶static屬性的全局變量和函數(shù)都是共有的,可以被其他模塊訪問
7.6符號(hào)解析
鏈接器解析符號(hào)引用方法:每個(gè)引用與它輸入的可重定位目標(biāo)文件的符號(hào)表中的一個(gè)確定的符號(hào)定義聯(lián)系起來。 編譯器只允許每個(gè)模塊每個(gè)本地符號(hào)只有一個(gè)定義。 編譯器還確保靜態(tài)本地變量,它們也會(huì)有本地鏈接器符號(hào),擁有唯一的名字。
7.6.1鏈接器如何解析多重定義的全局符號(hào)
在編譯時(shí):編譯器向匯編器輸出每個(gè)全局符號(hào),或者是強(qiáng)或弱,而匯編器把這個(gè)信息隱含地編碼在可重定位目標(biāo)文件的符號(hào)表里。 強(qiáng)符號(hào):函數(shù)和已初始化的全局變量。 弱符號(hào):未初始化的全局變量。 Unix鏈接器關(guān)于多重定義符號(hào)的規(guī)則: 1.不允許有多個(gè)強(qiáng)符號(hào) 2.如果有一個(gè)強(qiáng)符號(hào)和多個(gè)弱符號(hào),選強(qiáng)符號(hào) 3.如有多個(gè)弱符號(hào),則從弱符號(hào)中任意選擇一個(gè)。
7.6.2與靜態(tài)庫的連接
靜態(tài)庫:將所有相關(guān)的目標(biāo)模塊打包成為一個(gè)單獨(dú)的文件7.7重定位 重定位兩步: 1.重定位節(jié)和符號(hào)定義 2.重定位節(jié)中的符號(hào)引用。
重定位條目:
8.可執(zhí)行目標(biāo)文件
9.加載可執(zhí)行目標(biāo)文件
加載:將程序拷貝到存儲(chǔ)器并運(yùn)行的過程 在32位Linux系統(tǒng)中代碼段從地址0x08048000處開始。10.動(dòng)態(tài)鏈接共享庫?
共享庫是一個(gè)目標(biāo),在運(yùn)行時(shí),可以加載到任意的存儲(chǔ)器地址,并和一個(gè)在存儲(chǔ)器中的程序鏈接起來。這個(gè)過程稱為動(dòng)態(tài)鏈接,是由動(dòng)態(tài)鏈接器的程序來執(zhí)行的。 通常用.so后綴來表示,稱為DLL(動(dòng)態(tài)鏈接庫)。 ? 1.在任何給定的文件系統(tǒng)中,對(duì)于一個(gè)庫只有一個(gè).so文件。所有引用該庫的可執(zhí)行目標(biāo)文件共享這個(gè).so文件中的代碼和數(shù)據(jù)。 2.一種共享方式就是隱式鏈接,基本的思路:當(dāng)創(chuàng)建可執(zhí)行文件時(shí),靜態(tài)執(zhí)行一些鏈接,然后在程序加載時(shí),動(dòng)態(tài)完成鏈接過程。 3.一種共享方式就是“顯式鏈接”,應(yīng)用程序被加載時(shí),動(dòng)態(tài)鏈接器加載和鏈接共享庫的情景。應(yīng)用程序還可能在它運(yùn)行時(shí)要求動(dòng)態(tài)鏈接器加載和鏈接任意共享庫,而無需在編譯時(shí)鏈接那些庫到應(yīng)用中。11.從應(yīng)用程序中加載和連接共享庫
12.處理目標(biāo)文件的工具
AR:創(chuàng)建靜態(tài)庫,插入、刪除、列出和提取成員。 STRINGS:列出一個(gè)目標(biāo)文件中所有可打印的字符串。 STRIP:從目標(biāo)文件中刪除符號(hào)的信息。
轉(zhuǎn)載于:https://www.cnblogs.com/zhengwei0712/p/5352535.html
總結(jié)
以上是生活随笔為你收集整理的《深入理解计算机系统》第七章读书笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle12c 在windonSer
- 下一篇: Navicat是如何连接到服务器的呢