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

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

動態鏈接庫的實現原理是什么?

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

大家好,我是小風哥,今天簡單聊聊動態鏈接庫的實現原理。IgD28資訊網——每日最新資訊28at.com

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

目標文件中主要有兩部分,代碼段和數據段,這兩部分里面分別包含什么內容呢?IgD28資訊網——每日最新資訊28at.com

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

第二個模塊引用了函數foo,foo的定義可以在第一個模塊找到。IgD28資訊網——每日最新資訊28at.com

這個過程叫做符號解析。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

接下來鏈接器會把數據段合并到一起,代碼段合并到一起并確定符號的內存地址,這個過程叫做重定位。IgD28資訊網——每日最新資訊28at.com

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

假設現在有兩個運行的程序和一個動態庫liba. so,動態庫中定了一個全局變量a,第一個程序把變量a修改為了10。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

現在數據的問題解決了,我們來看函數。IgD28資訊網——每日最新資訊28at.com

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

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

由于程序1的foo函數位于內存地址0x123這個位置,因此鏈接器將call指令后的地址修正為0x123。IgD28資訊網——每日最新資訊28at.com

這時CPU執行這條call指令就能正確的跳轉到第一個程序的foo函數。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

這時系統就出現了錯誤。IgD28資訊網——每日最新資訊28at.com

問題出在了哪里呢?IgD28資訊網——每日最新資訊28at.com

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

該怎么辦呢?IgD28資訊網——每日最新資訊28at.com

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

接下來我們依然以函數調用為例來講解。IgD28資訊網——每日最新資訊28at.com

那么這個中間層到底是什么呢?IgD28資訊網——每日最新資訊28at.com

答案就是got。IgD28資訊網——每日最新資訊28at.com

還記得剛才提到的每個程序都有自己的數據區嗎,這個got段就屬于數據區的一部分。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

注意剛提到每個程序都有自己的數據區,實際上對于動態庫來說也有自己的代碼區。IgD28資訊網——每日最新資訊28at.com

我們現在只需要知道每個程序運行在自己的地址空間中,這些地址空間最終會被映射到真正的物理內存,動態庫中的數據區會被映射到不同的內存區域,但代碼段會被映射到同一段物理內存中,從而實現共享的目的。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

接下來我們重點看進程地址空間中的動態庫布局。IgD28資訊網——每日最新資訊28at.com

注意看,動態庫的數據區和代碼區總是相鄰的,也就是代碼區和got段的相對位置總是不變的,而不管動態庫被放到了哪個位置。IgD28資訊網——每日最新資訊28at.com

多個程序也一樣,也就是代碼區和數據區的相對位置總是固定的,這個相對位置在編譯時編譯器就能確定。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

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

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

而如果CPU執行第二個程序中的foo函數,那么CPU同樣會進行相對跳轉,這不過這次跳轉到的是第二個程序的got表,然后發現foo的地址是0x456,然后開始執行第二個程序中的foo函數。IgD28資訊網——每日最新資訊28at.com

圖片圖片IgD28資訊網——每日最新資訊28at.com

這樣我們就實現了執行同一個指令但卻會跳轉到不同地址的目的,從而在不改動動態庫代碼的前提先實現共享。IgD28資訊網——每日最新資訊28at.com

而如果一個動態庫中引用了很多外部函數會怎么樣呢?IgD28資訊網——每日最新資訊28at.com

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

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

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

這樣,不管動態庫被加載到內存的哪個位置都能正確被各個程序共享。IgD28資訊網——每日最新資訊28at.com

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

圖片圖片IgD28資訊網——每日最新資訊28at.com

希望這篇對大家理解動態庫有幫助。IgD28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-92467-0.html動態鏈接庫的實現原理是什么?

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

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

下一篇: 三分鐘帶你秒懂CAS實現機制

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美女主播在线| 欧美日本一区二区高清播放视频| 亚洲欧美中文字幕| 狠狠色综合色区| 国产精品国产亚洲精品看不卡15| 免费人成精品欧美精品| 午夜亚洲视频| 日韩午夜视频在线观看| 黄色精品在线看| 国产精品久久久久久久久久ktv| 浪潮色综合久久天堂| 午夜精品一区二区三区在线播放 | 黄网站色欧美视频| 国产精品久久久久久久9999| 欧美成人日本| 久久综合久久美利坚合众国| 午夜精品视频在线| 麻豆精品一区二区综合av | 狂野欧美激情性xxxx欧美| 新狼窝色av性久久久久久| 老牛国产精品一区的观看方式| 欧美日韩国产探花| 欧美日韩国产区一| 国产一区二区福利| 国产视频一区二区在线观看| 国产美女精品在线| 国产欧美一区二区三区国产幕精品| 在线看不卡av| 亚洲高清电影| 亚洲国产日韩欧美在线99 | 99re热这里只有精品视频| 亚洲久久一区二区| 亚洲美女中出| 久久岛国电影| 久久久久国色av免费看影院 | 欧美日韩一区二区在线播放| 欧美色另类天堂2015| 国内在线观看一区二区三区| 一区二区三区视频在线| 99精品国产在热久久婷婷| 99在线精品观看| 另类激情亚洲| 国产视频一区在线观看一区免费| 国产免费一区二区三区香蕉精| 国产精品久久久久永久免费观看| 国产精品视区| 又紧又大又爽精品一区二区| 在线欧美日韩| 亚洲精选一区| 日韩系列在线| 亚洲曰本av电影| 欧美一级黄色网| 久久综合色婷婷| 欧美精品1区2区| 欧美sm视频| 欧美日韩一区成人| 国产精品黄色| 亚洲精品一区二区三区在线观看| 久久久久成人精品| 国产欧美日韩三级| 亚洲一区美女视频在线观看免费| 欧美一区二区三区另类| 麻豆成人在线| 国内成人精品视频| 99这里有精品| 久久成人在线| 欧美激情一区二区三区在线视频观看| 黄色亚洲网站| 久久精品中文| 欧美三级午夜理伦三级中视频| 亚洲欧洲精品一区二区三区波多野1战4 | 欧美性猛交xxxx乱大交退制版| 国产视频精品xxxx| 亚洲尤物精选| 国产精品久久夜| 亚洲桃花岛网站| 久久精品国产第一区二区三区| 国产精品系列在线| 亚洲国产欧美日韩精品| 美女久久网站| 亚洲国产日韩欧美在线图片| 亚洲女人天堂av| 免费在线看一区| 国产精品你懂的| 亚洲国产三级网| 亚洲在线观看免费| 欧美xart系列在线观看| 国产精品福利久久久| 亚洲视频在线看| 欧美成人午夜视频| 亚洲精品久久| 久久久亚洲欧洲日产国码αv| 欧美日韩精品欧美日韩精品| 伊人久久综合| 亚洲一区成人| 欧美精品九九| 一区二区三区在线视频播放| 亚洲香蕉伊综合在人在线视看| 免费中文日韩| 国产一区二区三区网站| 亚洲伊人久久综合| 国产精品萝li| 久久国产精品久久国产精品| 精久久久久久| 欧美亚洲系列| 国产精品激情av在线播放| 亚洲一区二区网站| 欧美成人中文字幕| 激情久久中文字幕| 美女91精品| 国内成+人亚洲+欧美+综合在线| 一区二区三区鲁丝不卡| 国产精品久久久久免费a∨大胸| 午夜欧美精品久久久久久久| 韩国三级在线一区| 午夜视频一区二区| 国产一区激情| 欧美超级免费视 在线| 日韩一区二区高清| 国产女人aaa级久久久级| 99热在线精品观看| 国产精品女主播在线观看| 亚洲一区二区三区免费视频 | 国产精品久久久久久久久免费桃花| 欧美色网在线| 亚洲一级一区| 一本色道精品久久一区二区三区| 亚洲乱亚洲高清| 亚洲美女一区| 麻豆精品在线视频| 欧美成人情趣视频| 国产精品v片在线观看不卡| 国产精品美女www爽爽爽视频| 国内精品久久国产| 亚洲一区国产视频| 欧美精品电影| 精久久久久久| 99国产精品视频免费观看| 欧美欧美全黄| 精品成人一区二区三区| 亚洲午夜精品国产| 老色鬼久久亚洲一区二区| 欧美丝袜一区二区| 欧美国产91| 欧美视频一区二区三区…| 欧美性一区二区| 国产农村妇女毛片精品久久莱园子| 韩国精品在线观看| 国产精品乱码人人做人人爱| 久久久久中文| 欧美日韩另类丝袜其他| 韩国亚洲精品| 久久高清免费观看| 免费观看成人www动漫视频| 欧美午夜精品久久久久久浪潮| 亚洲一区二区成人| 久久久久这里只有精品| 欧美激情视频在线播放| 国产精品swag| 久久精品成人| 99在线热播精品免费| 国外成人网址| 欧美激情第三页| 久久人人超碰| 久久综合九色综合久99| 亚洲日本视频| 国产欧美日韩免费看aⅴ视频| 国内成人精品一区| 六月天综合网| 亚洲曰本av电影| 99国产精品国产精品久久| 伊人久久成人| 国产欧美一区二区色老头 | 欧美国产日韩精品| 久久久久网站| 欧美一区二区福利在线| 亚洲视频一区二区在线观看| 欧美日韩国产色视频| 亚洲剧情一区二区| 在线日韩成人| 韩国v欧美v日本v亚洲v| 国产欧美精品久久| 国产精品视频自拍| 国产精品美女久久久| 欧美视频一区二区在线观看| 欧美全黄视频| 欧美女人交a| 欧美日韩国产一级| 欧美久久电影| 欧美日韩国产999| 欧美日韩国产在线播放| 欧美国产成人在线| 欧美精品色网| 欧美日韩极品在线观看一区| 欧美一区二区三区男人的天堂| 一区二区三区欧美成人| 激情成人综合网| 激情欧美丁香| 影音先锋日韩精品| 在线国产欧美| 国产精品一区二区三区成人| 国产精品久久久999| 欧美午夜片欧美片在线观看| 欧美日本一区二区视频在线观看 |