0x01
首先戴尸,Linux下粟焊,一個(gè)C語(yǔ)言的hello world程序如下:
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
然后使用gcc命令將這段代碼變成一個(gè)可執(zhí)行程序。
$ gcc -g -Wall 0_1_hello_world.c -o hello_world
0x02
先講gcc的過程孙蒙。
其中過程涉及到:預(yù)處理项棠、編譯、匯編和鏈接四個(gè)步驟挎峦。
只是gcc自動(dòng)完成了這一系列的步驟香追。
預(yù)處理
預(yù)處理是用來(lái)處理預(yù)處理命令的。
例如坦胶,c語(yǔ)言中的#include就是預(yù)處理命令透典,它的作用是把頭文件的內(nèi)容包含到本文件中晴楔。(大一就學(xué)了好嗎?)
$ gcc -E 0_1_hello_wolrd.c
$ gcc -E 0_1_hello_world.c > 0_1_hello_world.i
執(zhí)行上面第一條命令峭咒,可以在預(yù)處理后自動(dòng)停止后面的操作税弃,并將預(yù)處理的結(jié)果輸出到標(biāo)準(zhǔn)輸出。
執(zhí)行上面第二條命令凑队,可以得到預(yù)處理后的文件则果,很明顯能看出,預(yù)處理后的文件是一個(gè)后綴名為i的文件漩氨。
這個(gè)時(shí)候西壮,我才明白,當(dāng)時(shí)學(xué)習(xí)c語(yǔ)言的時(shí)候?yàn)槭裁凑f(shuō)千萬(wàn)不能在頭文件中定義全局變量叫惊。
答案是:
因?yàn)槎x全局變量的代碼會(huì)存在于所有以#include包含該頭文件的文件中款青,也就是說(shuō),所有的這些文件赋访,都會(huì)定義一個(gè)同樣的全局變量可都,這樣不可避免的就會(huì)引起沖突。
編譯
編譯蚓耽,就是對(duì)源代碼進(jìn)行語(yǔ)法分析,并優(yōu)化產(chǎn)生對(duì)應(yīng)的匯編代碼的過程旋炒。
簡(jiǎn)單的說(shuō)步悠,編譯做的事情就是:
**源碼---->匯編代碼 **
同樣,gcc也可以讓你看到編譯后的匯編代碼瘫镇。
$ gcc -S 0_1_hello_world.c -o hello_world.s
-S這個(gè)參數(shù)是啥意思呢鼎兽?
就是讓gcc在編譯完成后停止后面的動(dòng)作。
可以看到铣除,源碼編譯完成后的匯編代碼谚咬,是一個(gè)后綴名為s的文件。
匯編
匯編尚粘,就是把源碼變成可執(zhí)行的指令择卦,并生成目標(biāo)文件。
粗俗一點(diǎn)講郎嫁,就是把一堆你認(rèn)識(shí)的代碼變成計(jì)算機(jī)認(rèn)識(shí)的指令秉继。
$ gcc -c 0_1_hello_world.c -o 0_1_hello_wolrd.o
此指令作用在此就不贅述了。
鏈接
這一步驟泽铛,大概大學(xué)是教過的吧尚辑,但的確是完全還給老師,不記得了盔腔。
鏈接杠茬,就是把各個(gè)目標(biāo)文件(包括庫(kù)文件)鏈接成為一個(gè)可執(zhí)行的程序月褥。這里面涉及的東西就太多了,什么地址和空間的分配啥的....
在Linux里面瓢喉,這個(gè)是由GNU的鏈接器ld完成的吓坚。
**整個(gè)gcc的過程,可以用gcc的-v參數(shù)查看完成和詳細(xì)的編譯過程
$ gcc -g -Wall -v 0_1_hello_world.c -o hello_world
0x03
一個(gè)可執(zhí)行的文件灯荧,里面是什么樣的呢礁击?
Linux下面的二進(jìn)制可執(zhí)行文件的格式一般都是ELF。
可以使用readelf命令來(lái)查看ELF格式逗载。
然后你會(huì)看到一大堆不是很懂的東西....
包括ELF Header哆窿、Section Headers、Key to Flags等...
0x04
一個(gè)程序 到底是怎么run起來(lái)的厉斟?
在Linux下挚躯,可以用strace這個(gè)命令來(lái)跟蹤系統(tǒng)的調(diào)用,從而明白這個(gè)程序是怎么運(yùn)行的擦秽,調(diào)用了一些什么码荔。
$ strace ./hello_world
strace命令顯示的是hello_world這個(gè)程序開始執(zhí)行后的所有輸出。
0x05
此文是之前瞄了一眼同事的Linux內(nèi)核相關(guān)書籍后總結(jié)整理的感挥,僅為記錄缩搅,知識(shí)相對(duì)較深。對(duì)于除Linux內(nèi)核開發(fā)人員之外的人触幼,大概都不怎么會(huì)用到硼瓣。
算是自己記錄一下冷知識(shí)吧。