久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx

Linux 程序編譯過程的來龍去脈

2021-02-12    分類: 網(wǎng)站建設(shè)

大家肯定都知道計算機程序設(shè)計語言通常分為機器語言、匯編語言和高級語言三類。高級語言需要通過翻譯成機器語言才能執(zhí)行,而翻譯的方式分為兩種,一種是編譯型,另一種是解釋型,因此我們基本上將高級語言分為兩大類,一種是編譯型語言,例如C,C++,Java,另一種是解釋型語言,例如Python、Ruby、MATLAB 、JavaScript。
本文將介紹如何將高層的C/C++語言編寫的程序轉(zhuǎn)換成為處理器能夠執(zhí)行的二進(jìn)制代碼的過程,包括四個步驟:
預(yù)處理(Preprocessing)
編譯(Compilation)
匯編(Assembly)
鏈接(Linking)
Linux 程序編譯過程的來龍去脈
GCC 工具鏈介紹
通常所說的GCC是GUN Compiler Collection的簡稱,是Linux系統(tǒng)上常用的編譯工具。GCC工具鏈軟件包括GCC、Binutils、C運行庫等。
GCC
GCC(GNU C Compiler)是編譯工具。本文所要介紹的將C/C++語言編寫的程序轉(zhuǎn)換成為處理器能夠執(zhí)行的二進(jìn)制代碼的過程即由編譯器完成。
Binutils
一組二進(jìn)制程序處理工具,包括:addr2line、ar、objcopy、objdump、as、ld、ldd、readelf、size等。這一組工具是開發(fā)和調(diào)試不可缺少的工具,分別簡介如下:
addr2line:用來將程序地址轉(zhuǎn)換成其所對應(yīng)的程序源文件及所對應(yīng)的代碼行,也可以得到所對應(yīng)的函數(shù)。該工具將幫助調(diào)試器在調(diào)試的過程中定位對應(yīng)的源代碼位置。
as:主要用于匯編,有關(guān)匯編的詳細(xì)介紹請參見后文。
ld:主要用于鏈接,有關(guān)鏈接的詳細(xì)介紹請參見后文。
ar:主要用于創(chuàng)建靜態(tài)庫。為了便于初學(xué)者理解,在此介紹動態(tài)庫與靜態(tài)庫的概念:
如果要將多個.o目標(biāo)文件生成一個庫文件,則存在兩種類型的庫,一種是靜態(tài)庫,另一種是動態(tài)庫。
在windows中靜態(tài)庫是以 .lib 為后綴的文件,共享庫是以 .dll 為后綴的文件。在linux中靜態(tài)庫是以.a為后綴的文件,共享庫是以.so為后綴的文件。
靜態(tài)庫和動態(tài)庫的不同點在于代碼被載入的時刻不同。靜態(tài)庫的代碼在編譯過程中已經(jīng)被載入可執(zhí)行程序,因此體積較大。共享庫的代碼是在可執(zhí)行程序運行時才載入內(nèi)存的,在編譯過程中僅簡單的引用,因此代碼體積較小。在Linux系統(tǒng)中,可以用ldd命令查看一個可執(zhí)行程序依賴的共享庫。
如果一個系統(tǒng)中存在多個需要同時運行的程序且這些程序之間存在共享庫,那么采用動態(tài)庫的形式將更節(jié)省內(nèi)存。
ldd:可以用于查看一個可執(zhí)行程序依賴的共享庫。
objcopy:將一種對象文件翻譯成另一種格式,譬如將.bin轉(zhuǎn)換成.elf、或者將.elf轉(zhuǎn)換成.bin等。
objdump:主要的作用是反匯編。有關(guān)反匯編的詳細(xì)介紹,請參見后文。
readelf:顯示有關(guān)ELF文件的信息,請參見后文了解更多信息。
size:列出可執(zhí)行文件每個部分的尺寸和總尺寸,代碼段、數(shù)據(jù)段、總大小等,請參見后文了解使用size的具體使用實例。
C運行庫
C語言標(biāo)準(zhǔn)主要由兩部分組成:一部分描述C的語法,另一部分描述C標(biāo)準(zhǔn)庫。C標(biāo)準(zhǔn)庫定義了一組標(biāo)準(zhǔn)頭文件,每個頭文件中包含一些相關(guān)的函數(shù)、變量、類型聲明和宏定義,譬如常見的printf函數(shù)便是一個C標(biāo)準(zhǔn)庫函數(shù),其原型定義在stdio頭文件中。
C語言標(biāo)準(zhǔn)僅僅定義了C標(biāo)準(zhǔn)庫函數(shù)原型,并沒有提供實現(xiàn)。因此,C語言編譯器通常需要一個C運行時庫(C Run Time Libray,CRT)的支持。C運行時庫又常簡稱為C運行庫。與C語言類似,C++也定義了自己的標(biāo)準(zhǔn),同時提供相關(guān)支持庫,稱為C++運行時庫。
準(zhǔn)備工作
由于GCC工具鏈主要是在Linux環(huán)境中進(jìn)行使用,因此本文也將以Linux系統(tǒng)作為工作環(huán)境。為了能夠演示編譯的整個過程,本節(jié)先準(zhǔn)備一個C語言編寫的簡單Hello程序作為示例,其源代碼如下所示:
編譯過程
1.預(yù)處理
預(yù)處理的過程主要包括以下過程:
將所有的#define刪除,并且展開所有的宏定義,并且處理所有的條件預(yù)編譯指令,比如#if #ifdef #elif #else #endif等。
處理#include預(yù)編譯指令,將被包含的文件插入到該預(yù)編譯指令的位置。
刪除所有注釋“//”和“/* */”。
添加行號和文件標(biāo)識,以便編譯時產(chǎn)生調(diào)試用的行號及編譯錯誤警告行號。
保留所有的#pragma編譯器指令,后續(xù)編譯過程需要使用它們。使用gcc進(jìn)行預(yù)處理的命令如下:
hello.i文件可以作為普通文本文件打開進(jìn)行查看,其代碼片段如下所示:
2.編譯
編譯過程就是對預(yù)處理完的文件進(jìn)行一系列的詞法分析,語法分析,語義分析及優(yōu)化后生成相應(yīng)的匯編代碼。
使用gcc進(jìn)行編譯的命令如下:
上述命令生成的匯編程序hello.s的代碼片段如下所示,其全部為匯編代碼。
3.匯編
匯編過程調(diào)用對匯編代碼進(jìn)行處理,生成處理器能識別的指令,保存在后綴為.o的目標(biāo)文件中。由于每一個匯編語句幾乎都對應(yīng)一條處理器指令,因此,匯編相對于編譯過程比較簡單,通過調(diào)用Binutils中的匯編器as根據(jù)匯編指令和處理器指令的對照表一一翻譯即可。
當(dāng)程序由多個源代碼文件構(gòu)成時,每個文件都要先完成匯編工作,生成.o目標(biāo)文件后,才能進(jìn)入下一步的鏈接工作。注意:目標(biāo)文件已經(jīng)是最終程序的某一部分了,但是在鏈接之前還不能執(zhí)行。
使用gcc進(jìn)行匯編的命令如下:
注意:hello.o目標(biāo)文件為ELF(Executable and Linkable Format)格式的可重定向文件。
4.鏈接
鏈接也分為靜態(tài)鏈接和動態(tài)鏈接,其要點如下:
靜態(tài)鏈接是指在編譯階段直接把靜態(tài)庫加入到可執(zhí)行文件中去,這樣可執(zhí)行文件會比較大。鏈接器將函數(shù)的代碼從其所在地(不同的目標(biāo)文件或靜態(tài)鏈接庫中)拷貝到最終的可執(zhí)行程序中。為創(chuàng)建可執(zhí)行文件,鏈接器必須要完成的主要任務(wù)是:符號解析(把目標(biāo)文件中符號的定義和引用聯(lián)系起來)和重定位(把符號定義和內(nèi)存地址對應(yīng)起來然后修改所有對符號的引用)。
動態(tài)鏈接則是指鏈接階段僅僅只加入一些描述信息,而程序執(zhí)行時再從系統(tǒng)中把相應(yīng)動態(tài)庫加載到內(nèi)存中去。
在Linux系統(tǒng)中,gcc編譯鏈接時的動態(tài)庫搜索路徑的順序通常為:首先從gcc命令的參數(shù)-L指定的路徑尋找;再從環(huán)境變量LIBRARY_PATH指定的路徑尋址;再從默認(rèn)路徑/lib、/usr/lib、/usr/local/lib尋找。
在Linux系統(tǒng)中,執(zhí)行二進(jìn)制文件時的動態(tài)庫搜索路徑的順序通常為:首先搜索編譯目標(biāo)代碼時指定的動態(tài)庫搜索路徑;再從環(huán)境變量LD_LIBRARY_PATH指定的路徑尋址;再從配置文件/etc/ld.so.conf中指定的動態(tài)庫搜索路徑;再從默認(rèn)路徑/lib、/usr/lib尋找。
在Linux系統(tǒng)中,可以用ldd命令查看一個可執(zhí)行程序依賴的共享庫。
由于鏈接動態(tài)庫和靜態(tài)庫的路徑可能有重合,所以如果在路徑中有同名的靜態(tài)庫文件和動態(tài)庫文件,比如libtest.a和libtest.so,gcc鏈接時默認(rèn)優(yōu)先選擇動態(tài)庫,會鏈接libtest.so,如果要讓gcc選擇鏈接libtest.a則可以指定gcc選項-static,該選項會強制使用靜態(tài)庫進(jìn)行鏈接。以Hello World為例:
如果使用命令“gcc hello.c -o hello”則會使用動態(tài)庫進(jìn)行鏈接,生成的ELF可執(zhí)行文件的大小(使用Binutils的size命令查看)和鏈接的動態(tài)庫(使用Binutils的ldd命令查看)如下所示:
如果使用命令“gcc -static hello.c -o hello”則會使用靜態(tài)庫進(jìn)行鏈接,生成的ELF可執(zhí)行文件的大小(使用Binutils的size命令查看)和鏈接的動態(tài)庫(使用Binutils的ldd命令查看)如下所示:
鏈接器鏈接后生成的最終文件為ELF格式可執(zhí)行文件,一個ELF可執(zhí)行文件通常被鏈接為不同的段,常見的段譬如.text、.data、.rodata、.bss等段。
分析ELF文件
1.ELF文件的段
ELF文件格式如下圖所示,位于ELF Header和Section Header Table之間的都是段(Section)。一個典型的ELF文件包含下面幾個段:
.text:已編譯程序的指令代碼段。
.rodata:ro代表read only,即只讀數(shù)據(jù)(譬如常數(shù)const)。
.data:已初始化的C程序全局變量和靜態(tài)局部變量。
.bss:未初始化的C程序全局變量和靜態(tài)局部變量。
.debug:調(diào)試符號表,調(diào)試器用此段的信息幫助調(diào)試。
Linux 程序編譯過程的來龍去脈
可以使用readelf -S查看其各個section的信息如下:
2.反匯編ELF
由于ELF文件無法被當(dāng)做普通文本文件打開,如果希望直接查看一個ELF文件包含的指令和數(shù)據(jù),需要使用反匯編的方法。

當(dāng)前文章:Linux 程序編譯過程的來龍去脈
網(wǎng)站URL:http://www.js-pz168.com/news11/100611.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航品牌網(wǎng)站制作建站公司軟件開發(fā)虛擬主機網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx
亚洲人一二三区| 韩国在线一区二区| 国产精品99久久久久久宅男| 91中文字精品一区二区| 水蜜桃一区二区| 日韩亚洲欧美成人一区| 中文字幕一区免费在线观看| 美女mm1313爽爽久久久蜜臀| 91热门视频在线观看| 亚洲午夜精品一区二区| 精品国产sm最大网站免费看| 亚洲午夜日本在线观看| 成人午夜精品在线| 视频一区二区在线| 亚洲精品在线免费播放| 五月天丁香久久| 3d蒂法精品啪啪一区二区免费| 亚洲一区二区三区加勒比| 精品国产青草久久久久福利| 亚洲高清免费观看高清完整版在线观看 | 亚洲综合免费观看高清完整版 | 国内国产精品久久| 精品视频在线观看| 91精选在线观看| 亚洲免费电影在线| 成人动漫一区二区三区| 亚洲人成网站在线播放2019| 久久久夜色精品亚洲| 日韩综合小视频| 国产精品久久久久久久免费大片| 欧美日韩午夜精品| 亚洲狠狠丁香婷婷综合久久久| 成人一道本在线| 正在播放精油久久| 国产精品丝袜91| 激情欧美日韩一区二区| 日本免费一区二区三区| 久久午夜色播影院免费高清| 免费国产亚洲视频| 久久综合九九| 久久免费国产精品| 韩国v欧美v日本v亚洲v| 品久久久久久久久久96高清| 久久一二三国产| 狠狠色丁香久久婷婷综| 日韩欧美视频一区二区| 国产色产综合色产在线视频| 国产一区啦啦啦在线观看| 日韩一二三区不卡在线视频| 国产亚洲综合色| 国产精品小仙女| 色先锋aa成人| 亚洲精品成a人| 97久久精品午夜一区二区| 7777女厕盗摄久久久| 天堂久久久久va久久久久| 久久精品人成| 久久久www成人免费毛片麻豆| 国产一区二区三区黄视频| 艳色歌舞团一区二区三区| 国产精品高潮久久久久无| 波波电影院一区二区三区| 欧美日韩精品欧美日韩精品一综合| 亚洲午夜国产一区99re久久| 精品国产乱码久久久久久丨区2区| 精品乱码亚洲一区二区不卡| 精品无人码麻豆乱码1区2区| 在线免费观看成人网| 樱桃国产成人精品视频| 国产精品视频免费一区| 久久影院午夜论| 高清成人免费视频| 欧美日本乱大交xxxxx| 日本免费在线视频不卡一不卡二| 欧美影视一区二区| 综合激情成人伊人| 国产精品久久久久久久久久久久午夜片 | 精品久久国产字幕高潮| 国产成人在线视频播放| 精品视频在线视频| 免费黄网站欧美| 色婷婷综合在线| 视频一区中文字幕国产| 亚洲黄色成人久久久| 亚洲中国最大av网站| 欧美激情专区| 亚洲人成精品久久久久| 精品免费日产一区一区三区免费| 久久久午夜精品理论片中文字幕| 成人妖精视频yjsp地址| 欧美一级生活片| 国产a视频精品免费观看| 91精品在线一区二区| 国产一区二区美女诱惑| 欧美日本在线观看| 国产精品综合网| 制服丝袜成人动漫| 国产成人综合亚洲网站| 日韩亚洲欧美综合| 成人免费黄色大片| 精品电影一区二区| 99精品国产一区二区三区不卡| 欧美精品一区二区高清在线观看| 成人ar影院免费观看视频| 精品国产一区二区三区久久久蜜月 | 国产欧美精品一区aⅴ影院 | 国产精品不卡一区| 精品高清视频| 亚洲欧美激情视频在线观看一区二区三区| 国内精品久久国产| 亚洲伦理在线精品| 日韩一区二区电影在线观看| 性欧美疯狂xxxxbbbb| 在线观看日韩片| 久久66热偷产精品| 91精品久久久久久久99蜜桃 | 精品少妇一区二区三区视频免付费 | 欧美日韩精品一区二区三区| 国产一区二区伦理片| 日韩欧美久久久| 91成人伦理在线电影| 国产精品女上位| 欧美一级爽aaaaa大片| 亚洲高清三级视频| 欧美在线影院一区二区| 国产一区二区0| 亚洲精品一区在线观看| 国产91精品入口17c| 亚洲日本在线观看| 亚洲精品视频一区二区三区| 免费成人在线网站| 欧美一级黄色大片| 91麻豆精品在线观看| 亚洲婷婷国产精品电影人久久| 天堂√在线观看一区二区| 免费观看在线综合色| 欧美一级一区二区| 91黄在线观看| 玉米视频成人免费看| 日本道色综合久久| 国产大片一区二区| 欧美高清在线一区| 欧洲视频一区二区三区| 蜜臀av性久久久久蜜臀aⅴ| 欧美一区二区三区公司| 成人做爰66片免费看网站| 亚洲一区影音先锋| 欧美日韩一区视频| 91麻豆免费视频| 一区二区三区高清不卡| 欧美性猛交xxxxxx富婆| 成人91在线观看| 亚洲欧美一区二区三区极速播放| 在线看视频不卡| 成人一级视频在线观看| 成人欧美一区二区三区| 色嗨嗨av一区二区三区| 成人app在线观看| 一区二区三区在线播| 欧美三级韩国三级日本一级| 99久久精品久久久久久清纯| 亚洲精品一二三| 欧美日本一道本在线视频| 国产chinese精品一区二区| 香蕉影视欧美成人| 欧美一区国产二区| 久久久7777| 国内外成人在线视频| 中文av字幕一区| 日本韩国欧美在线| 7777精品久久久大香线蕉小说 | 日韩免费av一区二区三区| 国精产品一区一区三区mba视频| 欧美激情一区三区| 91福利在线免费观看| 97超级在线观看免费高清完整版电视剧| 亚洲高清在线精品| 精品理论电影在线| 亚洲一卡二卡三卡| 99久久精品国产导航| 午夜欧美一区二区三区在线播放| 日韩精品一区二区三区视频| 日本高清不卡一区二区三| 国产suv精品一区二区883| 亚洲免费在线视频| 91精品蜜臀在线一区尤物| 蜜桃传媒视频麻豆第一区免费观看 | 国产精品99久久久久久似苏梦涵| 最新热久久免费视频| 欧美日韩高清在线播放| 精品国产一区二区三区麻豆小说 | 欧美日韩亚洲另类| 国产一区二区自拍| 精品亚洲免费视频| 亚洲日本免费电影| 欧美一级免费观看| 色综合电影网| 91麻豆国产在线观看| 麻豆国产欧美日韩综合精品二区| 国产精品美女久久久久久久久久久 |