日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

動態(tài)鏈接庫的實現(xiàn)原理是什么?

來源: 責編: 時間:2024-06-06 17:41:54 152觀看
導讀大家好,我是小風哥,今天簡單聊聊動態(tài)鏈接庫的實現(xiàn)原理。假設有這樣兩段代碼,第一段代碼定義了一個全量變量a以及函數(shù)foo,函數(shù)foo中引用了下一段代碼中定義的全局變量b。圖片第二段代碼定義了全局變量b以及main函數(shù),同時在m

大家好,我是小風哥,今天簡單聊聊動態(tài)鏈接庫的實現(xiàn)原理。Ofu28資訊網(wǎng)——每日最新資訊28at.com

假設有這樣兩段代碼,第一段代碼定義了一個全量變量a以及函數(shù)foo,函數(shù)foo中引用了下一段代碼中定義的全局變量b。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

第二段代碼定義了全局變量b以及main函數(shù),同時在main函數(shù)中調用了第一個模塊中定義的函數(shù)foo。Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來編譯器出場,編譯器會把這個兩個源文件編譯成對應的目標文件。Ofu28資訊網(wǎng)——每日最新資訊28at.com

目標文件中主要有兩部分,代碼段和數(shù)據(jù)段,這兩部分里面分別包含什么內(nèi)容呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

我們定義的全局變量會被放到數(shù)據(jù)段,代碼被編譯生成的二進制指令會被放到代碼段,第二個目標文件也一樣。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

注意看第一段代碼,這里引用了一個其它模塊定義的全局變量b,這一信息記錄在第一個目標文件,第二段代碼引用了其它模塊定義的函數(shù)foo,這一信息記錄在第二個目標文件。Ofu28資訊網(wǎng)——每日最新資訊28at.com

注意看第一段代碼,這里定一個全局變量a和函數(shù)foo,我們記錄下來,第二段代碼定義了全局變量b和函數(shù)main,同樣記錄下來。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

接著我們開始一個叫做連連看的游戲。Ofu28資訊網(wǎng)——每日最新資訊28at.com

第一個模塊引用了變量b,變量b的定義可以在第二個模塊找到。Ofu28資訊網(wǎng)——每日最新資訊28at.com

第二個模塊引用了函數(shù)foo,foo的定義可以在第一個模塊找到。Ofu28資訊網(wǎng)——每日最新資訊28at.com

這個過程叫做符號解析。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

這里看到的引用以及定義的符號保存在所謂的符號表中。Ofu28資訊網(wǎng)——每日最新資訊28at.com

而如果第二個模塊引用了一個叫做bar的變量,鏈接器翻遍所有其它模塊都沒找到bar這個符號的定義,而只找到了一個叫做foo的定義,這時鏈接器就會報一個叫做符合未定義的錯誤,這個錯誤寫c/c++的程序員一定不陌生。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來鏈接器會把數(shù)據(jù)段合并到一起,代碼段合并到一起并確定符號的內(nèi)存地址,這個過程叫做重定位。Ofu28資訊網(wǎng)——每日最新資訊28at.com

了解了這些就可以開始講動態(tài)庫的實現(xiàn)原理了,動態(tài)庫又叫做共享庫,我們的問題是,動態(tài)庫是怎么實現(xiàn)可以被程序之間共享的呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

假設現(xiàn)在有兩個運行的程序和一個動態(tài)庫liba. so,動態(tài)庫中定了一個全局變量a,第一個程序把變量a修改為了10。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

然后第二個程序開始運行,第二個程序也使用該動態(tài)庫,然后把全局變量a修改為了20。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

這是第一個程序運行一段時間后決定打印變量a,這時你會驚訝的發(fā)現(xiàn)變量a從10變成了20,但是為什么。Ofu28資訊網(wǎng)——每日最新資訊28at.com

原因就是這兩個程序共享了同一個數(shù)據(jù)段,所以一個程序對數(shù)據(jù)的修改對另一人程序是可見的,因此動態(tài)庫中的數(shù)據(jù)段不能共享,每個程序需要有自己的數(shù)據(jù)段。Ofu28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在數(shù)據(jù)的問題解決了,我們來看函數(shù)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

假設動態(tài)庫liba.so需要引用外部定義的foo函數(shù),由于程序1和程序2都使用了該動態(tài)庫,因此必須定義出foo函數(shù)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

我們知道函數(shù)調用最終會被編譯器翻譯成call機器指令后跟函數(shù)地址。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來我們需要解析出foo函數(shù)的地址到底是什么,這就是剛才我們提到的重定位,只不過動態(tài)庫將這一過程推遲到了運行時。Ofu28資訊網(wǎng)——每日最新資訊28at.com

由于程序1的foo函數(shù)位于內(nèi)存地址0x123這個位置,因此鏈接器將call指令后的地址修正為0x123。Ofu28資訊網(wǎng)——每日最新資訊28at.com

這時CPU執(zhí)行這條call指令就能正確的跳轉到第一個程序的foo函數(shù)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

而第二個程序的foo函數(shù)為內(nèi)存地址0x456這個位置,接下來第二個程序開始運行,CPU開始執(zhí)行foo函數(shù),由于第二個程序的foo函數(shù)在0x456,因此我們希望CPU能跳轉到這里,但由于動態(tài)庫中call指令后跟的是0x123這個內(nèi)存地址,因此CPU執(zhí)行foo函數(shù)時依然會跳轉到第一個程序的foo函數(shù)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

這時系統(tǒng)就出現(xiàn)了錯誤。Ofu28資訊網(wǎng)——每日最新資訊28at.com

問題出在了哪里呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

主要是call這條機器指令,這條指令后跟了一個絕對的內(nèi)存地址,而不要忘了,這條指令或者說動態(tài)庫是要被各個程序共享的,顯然我們不能直接使用絕對地址。Ofu28資訊網(wǎng)——每日最新資訊28at.com

該怎么辦呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

計算機中所有問題都可以通過增加一個中間層來解決。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

這樣我們就摒棄了直接調用,而采用間接調用。Ofu28資訊網(wǎng)——每日最新資訊28at.com

而我們這里對函數(shù)的討論對于全局變量的應用也是一樣的道理,全局變量的使用也存在同樣的問題,只不過是從函數(shù)調用變成了內(nèi)存讀寫,解決問題的方法一樣,我們從直接應用改為間接引用。Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來我們依然以函數(shù)調用為例來講解。Ofu28資訊網(wǎng)——每日最新資訊28at.com

那么這個中間層到底是什么呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

答案就是got。Ofu28資訊網(wǎng)——每日最新資訊28at.com

還記得剛才提到的每個程序都有自己的數(shù)據(jù)區(qū)嗎,這個got段就屬于數(shù)據(jù)區(qū)的一部分。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

got中有什么呢?got中記錄了引用的全局變量或者函數(shù)的地址,在程序運行時鏈接器會找到foo的內(nèi)存地址,然后填到got表中,這樣通過查got表我們就能知道函數(shù)foo的內(nèi)存地址了。Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來的問題就是當CPU調用foo函數(shù)時怎么才能知道got表在哪里呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

注意剛提到每個程序都有自己的數(shù)據(jù)區(qū),實際上對于動態(tài)庫來說也有自己的代碼區(qū)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

我們現(xiàn)在只需要知道每個程序運行在自己的地址空間中,這些地址空間最終會被映射到真正的物理內(nèi)存,動態(tài)庫中的數(shù)據(jù)區(qū)會被映射到不同的內(nèi)存區(qū)域,但代碼段會被映射到同一段物理內(nèi)存中,從而實現(xiàn)共享的目的。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來我們重點看進程地址空間中的動態(tài)庫布局。Ofu28資訊網(wǎng)——每日最新資訊28at.com

注意看,動態(tài)庫的數(shù)據(jù)區(qū)和代碼區(qū)總是相鄰的,也就是代碼區(qū)和got段的相對位置總是不變的,而不管動態(tài)庫被放到了哪個位置。Ofu28資訊網(wǎng)——每日最新資訊28at.com

多個程序也一樣,也就是代碼區(qū)和數(shù)據(jù)區(qū)的相對位置總是固定的,這個相對位置在編譯時編譯器就能確定。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在foo會被編譯成call指令,而程序在加載時鏈接器會向got段中寫入foo的內(nèi)存地址,顯然兩個程序的foo地址是不一樣的。Ofu28資訊網(wǎng)——每日最新資訊28at.com

接下來CPU開始執(zhí)行第一個程序的call指令,此時CPU會做一個相對跳轉,這個跳轉距離是編譯器確定的,CPU會跳轉到got表,然后查找foo的地址發(fā)現(xiàn)是0x123,然后開始執(zhí)行0x123這個位置的函數(shù)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

而如果CPU執(zhí)行第二個程序中的foo函數(shù),那么CPU同樣會進行相對跳轉,這不過這次跳轉到的是第二個程序的got表,然后發(fā)現(xiàn)foo的地址是0x456,然后開始執(zhí)行第二個程序中的foo函數(shù)。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

這樣我們就實現(xiàn)了執(zhí)行同一個指令但卻會跳轉到不同地址的目的,從而在不改動動態(tài)庫代碼的前提先實現(xiàn)共享。Ofu28資訊網(wǎng)——每日最新資訊28at.com

而如果一個動態(tài)庫中引用了很多外部函數(shù)會怎么樣呢?Ofu28資訊網(wǎng)——每日最新資訊28at.com

這樣程序在啟動時鏈接器不得不對所有函數(shù)進行重定位,因此會拖慢程序啟動速度。Ofu28資訊網(wǎng)——每日最新資訊28at.com

而我們知道一個程序中不是所有的函數(shù)都會被調用到,經(jīng)常調用的都是少數(shù)幾個函數(shù),為了利用這一點編譯鏈接系統(tǒng)使用procedure linkage table, plt來推遲重定位這個過程,也就是程序在啟動時不進行函數(shù)重定位,而是推遲到真正調用函數(shù)時,沒用調用過的函數(shù)根本就不進行重定位,從而加快程序啟動速度。Ofu28資訊網(wǎng)——每日最新資訊28at.com

從這個一過程我們可以看到動態(tài)庫的這種間接調用實際上會對程序性能有一定影響,但相對于動態(tài)庫帶來的好處與便捷,這點影響可以忽略不計。Ofu28資訊網(wǎng)——每日最新資訊28at.com

這樣,不管動態(tài)庫被加載到內(nèi)存的哪個位置都能正確被各個程序共享。Ofu28資訊網(wǎng)——每日最新資訊28at.com

動態(tài)庫的這個特性被稱之為位置無關代碼,簡稱position-independent code, pic,這就是為什么你在編譯生成動態(tài)庫時要加上pic編譯選項的原因。Ofu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Ofu28資訊網(wǎng)——每日最新資訊28at.com

希望這篇對大家理解動態(tài)庫有幫助。Ofu28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-92467-0.html動態(tài)鏈接庫的實現(xiàn)原理是什么?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 為了全面監(jiān)控用戶行為,我寫了個超級前端工具庫!

下一篇: 三分鐘帶你秒懂CAS實現(xiàn)機制

標簽:
  • 熱門焦點
  • Find N3入網(wǎng):最高支持16+1TB

    OPPO將于近期登場的Find N3折疊屏目前已經(jīng)正式入網(wǎng),型號為PHN110。本次Find N3在外觀方面相比前兩代有很大的變化,不再是小號的橫向折疊屏,而是跟別的廠商一樣采用了較為常見的
  • 微軟邀請 Microsoft 365 商業(yè)用戶,測試視頻編輯器 Clipchamp

    8 月 1 日消息,微軟近日宣布即將面向 Microsoft 365 商業(yè)用戶,開放 Clipchamp 應用,邀請用戶通過該應用來編輯視頻。微軟于 2021 年收購 Clipchamp,隨后開始逐步整合到 Microsof
  • JVM優(yōu)化:實戰(zhàn)OutOfMemoryError異常

    一、Java堆溢出堆內(nèi)存中主要存放對象、數(shù)組等,只要不斷地創(chuàng)建這些對象,并且保證 GC Roots 到對象之間有可達路徑來避免垃 圾收集回收機制清除這些對象,當這些對象所占空間超過
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人員可能會涉及各種各樣的安全任務,包括但不限于:開發(fā)某些安全工具的插件,滿足自己特定的安全需求;自定義github搜索工具,快速查找所需的安全資料、漏洞poc、exp
  • 自律,給不了Keep自由!

    來源 | 互聯(lián)網(wǎng)品牌官作者 | 李大為編排 | 又耳 審核 | 谷曉輝自律能不能給用戶自由暫時不好說,但大概率不能給Keep自由。近日,全球最大的在線健身平臺Keep正式登陸港交所,努力
  • 一條抖音4億人圍觀 ! 這家MCN比無憂傳媒還野

    作者:Hiu 來源:互聯(lián)網(wǎng)品牌官01 擦邊少女空降熱搜,幕后推手曝光被網(wǎng)友譽為“純欲天花板”的女網(wǎng)紅井川里予,近期因為一組哥特風照片登上熱搜,引發(fā)了一場互聯(lián)網(wǎng)世界關于
  • 華為和江淮汽車合作開發(fā)百萬元問界MPV?雙方回應來了

    8月1日消息,郭明錤今天在社交平臺發(fā)文稱,華為正在和江淮汽車合作,開發(fā)售價在100萬元的問界MPV,預計在2024年第2季度量產(chǎn),銷量目標為上市首年交付5萬輛。
  • 三星折疊屏手機去年銷售近1000萬臺 今年目標定為1500萬

    7月29日消息,三星率先發(fā)力可折疊手機市場,在全球市場已經(jīng)取得了非常亮眼的成績,接下來會進一步鞏固和擴大這一優(yōu)勢。三星在推出Galaxy Z Flip5和Galax
  • OPPO K11搭載長壽版100W超級閃充:26分鐘充滿100%

    據(jù)此前官方宣布,OPPO將于7月25日也就是今天下午14:30舉辦新品發(fā)布會,屆時全新的OPPO K11將正式與大家見面,將主打旗艦影像,和同檔位競品相比,其最大的賣
Top 主站蜘蛛池模板: 方山县| 泊头市| 连云港市| 青岛市| 河津市| 福贡县| 漳平市| 镇安县| 拜泉县| 上蔡县| 曲麻莱县| 绥芬河市| 朔州市| 永靖县| 界首市| 桦南县| 宣威市| 正镶白旗| 香格里拉县| 洱源县| 静乐县| 濉溪县| 金阳县| 西昌市| 大理市| 黑河市| 龙海市| 松江区| 洛南县| 西华县| 双流县| 珠海市| 中西区| 德州市| 旌德县| 修武县| 岑溪市| 塘沽区| 玉龙| 永顺县| 元江|