程序的周邊

一:程序的誕生

平時(shí)使用gcc生成可執(zhí)行程序,gcc -g -Wall hello.c -o hello
整個(gè)過(guò)程涉及了預(yù)處理困曙、編譯传惠、匯編仿便、鏈接多個(gè)步驟体啰。

1. 預(yù)處理階段

將宏定義展開(kāi),將頭文件的內(nèi)容包含嗽仪,生成后綴為.i的預(yù)處理文件荒勇。

gcc/g++  -E  a.c  -o  a.i 

所以為什么全局變量不能在頭文件中定義,因?yàn)槎x全局變量的代碼會(huì)存在于所有include包含該頭文件的文件中闻坚。
一般的做法沽翔,將全局變量 使用extern 聲明在頭文件(eg:res.h)中,res.cpp中定義鲤氢,其他使用全局變量的文件包含該頭文件(res.h)

關(guān)于g++和gcc在這一階段的區(qū)別:g++ 區(qū)別于 gcc 會(huì)在部分頭文件和類(lèi)型定義前添加extern “C”搀擂,這個(gè)標(biāo)識(shí)符的作用把標(biāo)識(shí)符作用域的數(shù)據(jù)類(lèi)型采用gcc去編譯西潘。

2. 編譯階段:

對(duì)源代碼進(jìn)行語(yǔ)義分析卷玉,并優(yōu)化產(chǎn)生對(duì)應(yīng)的匯編代碼的過(guò)程。生成后綴.s的匯編文件

 gcc/g++  -S  a.c  -o  a.s

使用gcc 和 g++ 編譯結(jié)果對(duì)比圖:

編譯.PNG

對(duì)比發(fā)現(xiàn)函數(shù)的命名方式不一樣喷市,對(duì)于g++相种,因?yàn)閏++支持重載,所以編譯器會(huì)為每個(gè)函數(shù)重新更改名字品姓。

3. 匯編階段

將源碼翻譯成可執(zhí)行的指令寝并,并生成目標(biāo)文件。后綴為.o.

gcc/g++  -c  a.s  -o  a.o

匯編階段時(shí)腹备,gcc/g++內(nèi)部都是調(diào)用as匯編命令衬潦,在這里兩者是沒(méi)有區(qū)別的。

4. 鏈接階段

將各個(gè)目標(biāo)文件包括庫(kù)文件植酥,鏈接成一個(gè)可執(zhí)行程序镀岛,這個(gè)過(guò)程涉及 地址和空間的分配弦牡、符號(hào)解析、重定位等等漂羊,在linux下驾锰,該工作由 GNU的鏈接器 ld 完成。

gcc/g++ -o a a.o

我們可以使用 -v 選項(xiàng)查看完整和詳細(xì)的gcc編譯過(guò)程走越。

5.這里有一篇《關(guān)于gcc和g++編譯器分別對(duì)c與c++文件影響》

原文鏈接:https://blog.csdn.net/qq_21792169/article/details/85097822
版權(quán)聲明:本文為CSDN博主「HeroKern」的原創(chuàng)文章椭豫,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明旨指。

二:程序的構(gòu)成

linux下可執(zhí)行程序大部分是elf格式文件赏酥,可以使用 readelf 查看

readelf -h test
header.PNG
readelf -S test

[21] .dynamic DYNAMIC 0000000000200dc8 00000dc8
00000000000001f0 0000000000000010 WA 6 0 8
[22] .got PROGBITS 0000000000200fb8 00000fb8
0000000000000048 0000000000000008 WA 0 0 8
[23] .data PROGBITS 0000000000201000 00001000
0000000000000010 0000000000000000 WA 0 0 8
[24] .bss NOBITS 0000000000201010 00001010
0000000000000008 0000000000000000 WA 0 0 1
[25] .comment PROGBITS 0000000000000000 00001010
0000000000000029 0000000000000001 MS 0 0 1
[26] .symtab SYMTAB 0000000000000000 00001040
0000000000000600 0000000000000018 27 43 8
[27] .strtab STRTAB 0000000000000000 00001640
0000000000000205 0000000000000000 0 0 1
[28] .shstrtab STRTAB 0000000000000000 00001845
00000000000000fe 0000000000000000 0 0 1

可以看到比較熟悉的 data text bss等。
比較常見(jiàn)的段:

  1. text段:代碼段谆构,用于保存可執(zhí)行指令
  2. data段:初始化數(shù)據(jù)段今缚,保存有非0初始值的全局變量和靜態(tài)變量
  3. bss段:未初始化數(shù)據(jù)段,用于保存沒(méi)有初始化值或初值為0的全局變量和靜態(tài)變量低淡,當(dāng)程序加載時(shí)姓言,這些變量的值會(huì)被初始化為0。
  4. debug段:用于保存調(diào)試信息蔗蹋。
  5. dyamic段:用于保存動(dòng)態(tài)鏈接信息
  6. init段:用于保存進(jìn)程啟動(dòng)時(shí)的執(zhí)行程序何荚,當(dāng)進(jìn)程啟動(dòng)時(shí),系統(tǒng)會(huì)自動(dòng)執(zhí)行這部分代碼猪杭。
    等等吧餐塘。。皂吮。

關(guān)于程序內(nèi)存分區(qū)

代碼段戒傻、數(shù)據(jù)段、BSS段蜂筹、堆區(qū)需纳、映射段、棧區(qū)艺挪、內(nèi)核空間
參考 https://blog.csdn.net/shayne000/article/details/88547187

關(guān)于nm和ldd

nm 可以查看可執(zhí)行程序或庫(kù)的符號(hào)信息
ldd 可以查看可執(zhí)行程序運(yùn)行時(shí)依賴(lài)的庫(kù)文件
參考 https://www.cnblogs.com/xiaomanon/p/4203671.html

三:關(guān)于ABI兼容

1.API和ABI的區(qū)別

參考:https://blog.csdn.net/xinghun_4/article/details/7905298

API 應(yīng)用程序接口不翩,是編程接口。編寫(xiě)“應(yīng)用程序”時(shí)候調(diào)用的函數(shù)之類(lèi)的東西麻裳。 定義了源代碼和庫(kù)之間的接口口蝠,因此同樣的代碼可以在支持這個(gè)API的任何系統(tǒng)中編譯。
ABI 應(yīng)用程序二進(jìn)制接口津坑,是二進(jìn)制接口妙蔗,除非你直接使用匯編語(yǔ)言,這種接口一般是不能直接拿來(lái)用的疆瑰。允許編譯好的目標(biāo)代碼在使用兼容ABI的系統(tǒng)中無(wú)需改動(dòng)就能運(yùn)行.

2. ABI兼容

以下整理自知乎上一個(gè)答者眉反。

作者:Aman
    鏈接:https://www.zhihu.com/question/381069847/answer/1094118331
    來(lái)源:知乎
    著作權(quán)歸作者所有狞谱。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處禁漓。

詳細(xì)情況建議點(diǎn)擊上述鏈接直接查看原答者的回答

2.1什么是二進(jìn)制兼容性呢跟衅?

如1中API和ABI的說(shuō)明,假設(shè)你的應(yīng)用程序引用的一個(gè)庫(kù)某天更新了播歼,雖然 API 和調(diào)用方式基本沒(méi)變伶跷,但你需要重新編譯你的應(yīng)用程序才能使用這個(gè)庫(kù),那么一般說(shuō)這個(gè)庫(kù)是 Source compatible秘狞;反之叭莫,如果不需要重新編譯應(yīng)用程序就能使用新版本的庫(kù),那么說(shuō)這個(gè)庫(kù)跟它之前的版本是二進(jìn)制兼容的烁试。

2.2 怎么開(kāi)發(fā)二進(jìn)制兼容的程序呢

由于不同的 C++ 編譯器雇初、甚至不同版本的 C++ 編譯器的 Name mangling 算法可能有所不同,所以開(kāi)發(fā)二進(jìn)制兼容的庫(kù)的時(shí)候减响,一般使用 extern "C" 來(lái)抑制 Name mangling

#ifdef __cplusplus 
extern "C" {
#endif

// your code here

#ifdef __cplusplus
}
#endif

在開(kāi)發(fā)二進(jìn)制兼容的庫(kù)的時(shí)候靖诗,一定要避免使用 STL,因?yàn)椴煌?C++ 編譯器支示、不同版本的 C++ 編譯器攜帶的 STL 不具備二進(jìn)制兼容性刊橘,甚至同一個(gè)版本的 C++ 編譯器用戶(hù)也可能使用不同的 STL 替代自帶的 STL∷毯瑁或者說(shuō)促绵,二進(jìn)制兼容的接口應(yīng)該只使用 int32、double 等基礎(chǔ)數(shù)據(jù)類(lèi)型嘴纺,使用確定的 struct 甚至完全不使用 struct败晴、只提供抽象的 handle,或者純抽象接口栽渴。

2.3 這里有一個(gè)ABI不兼容的問(wèn)題例子

參考 https://www.cnblogs.com/Keeping-Fit/p/14251144.html

四:指令集

參考 https://www.cnblogs.com/johnnyzen/p/13224632.html

指令集 被應(yīng)用的指令集架構(gòu) 國(guó)產(chǎn)芯片
CISC 復(fù)雜指令集 x86 兆芯 amd64
RISC 精簡(jiǎn)指令集 mips 龍芯
RISC 精簡(jiǎn)指令集 arm 飛騰尖坤、華為鯤鵬
RISC 精簡(jiǎn)指令集 aarch64/arm64 飛騰
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市熔萧,隨后出現(xiàn)的幾起案子糖驴,更是在濱河造成了極大的恐慌僚祷,老刑警劉巖佛致,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異辙谜,居然都是意外死亡俺榆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)装哆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)罐脊,“玉大人定嗓,你說(shuō)我怎么就攤上這事∑甲溃” “怎么了宵溅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)上炎。 經(jīng)常有香客問(wèn)我恃逻,道長(zhǎng),這世上最難降的妖魔是什么藕施? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任寇损,我火速辦了婚禮,結(jié)果婚禮上裳食,老公的妹妹穿的比我還像新娘矛市。我一直安慰自己,他們只是感情好诲祸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布浊吏。 她就那樣靜靜地躺著,像睡著了一般救氯。 火紅的嫁衣襯著肌膚如雪卿捎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天径密,我揣著相機(jī)與錄音午阵,去河邊找鬼。 笑死享扔,一個(gè)胖子當(dāng)著我的面吹牛底桂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惧眠,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼籽懦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了氛魁?” 一聲冷哼從身側(cè)響起暮顺,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秀存,沒(méi)想到半個(gè)月后捶码,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡或链,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年惫恼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澳盐。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祈纯,死狀恐怖令宿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腕窥,我是刑警寧澤粒没,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站簇爆,受9級(jí)特大地震影響革娄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冕碟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一拦惋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧安寺,春花似錦厕妖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至迎捺,卻和暖如春举畸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凳枝。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工抄沮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人岖瑰。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓叛买,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蹋订。 傳聞我的和親對(duì)象是個(gè)殘疾皇子率挣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容