一步步编写操作系统 46 用c语言编写内核3
再把上節(jié)代碼貼出來(lái),
1 //int main(void) { 2 int _start(void) { 3 while(1); 4 return 0; 5 }有沒(méi)有同學(xué)想過(guò),這里寫一個(gè)_start函數(shù),讓其調(diào)用main函數(shù)如何?其實(shí)這是可以的,main函數(shù)并不是第一個(gè)函數(shù),它實(shí)際上也是被別人調(diào)用的,不過(guò)這是編譯器背后的策略啦,好奇心大的同學(xué)自己嘗試下吧。
雖然把函數(shù)名改成_start可以解決問(wèn)題,但我們習(xí)慣于main函數(shù)做為主函數(shù),不習(xí)慣函數(shù)用_start,于是用了-e來(lái)指定起始的函數(shù)名為main,所以代碼才鏈接正常。
也許有同學(xué)想過(guò),哎?我平時(shí)寫的程序也沒(méi)有_start啊,直接用gcc編譯后就能運(yùn)行,沒(méi)出過(guò)問(wèn)題啊。是啊,確實(shí)如您所說(shuō),由于我也沒(méi)深入研究過(guò),但咱們通過(guò)比較的方式,讓您自己悟出這里面的秘密。還是用上述代碼為例,gcc –o /tmp/test.bin kernel/main.c編譯鏈接,由于未加-c參數(shù),生成的test.bin不再是目標(biāo)文件而是可執(zhí)行文件。然后再用先編譯成目標(biāo)文件再鏈接成可執(zhí)行文件的方式,對(duì)比這兩個(gè)文件的區(qū)別。見圖
您看,test.bin是gcc直接生成的可執(zhí)行文件,它的大小是4586字節(jié)。而kernel.bin是經(jīng)過(guò)手動(dòng)編譯、鏈接這兩個(gè)步驟完成的,其文件大小是1777字節(jié)。這兩個(gè)文件的體積可是差了幾乎2倍呢。再看看這兩個(gè)文件中的符號(hào)信息,還是用nm命令,如圖
test.bin中共有34個(gè)符號(hào)(wc –l命令是用來(lái)統(tǒng)計(jì)輸出的行數(shù),一個(gè)符號(hào)占用一行,故34個(gè)符號(hào)),由于輸出太長(zhǎng)了,我們只截取了關(guān)鍵的部分,不過(guò)您看那些frame_dummy、data_start等,這并不是咱們代碼中存在的符號(hào),這說(shuō)明在編譯器在編譯過(guò)程中為咱們引用了別的代碼,這就是c運(yùn)行庫(kù)的功勞,目的是在調(diào)用main函數(shù)前做初始化環(huán)境等工作。您看,用白色方框圈出來(lái)的_start,這就是默認(rèn)的入口符號(hào),鏈接器還是用到了它,它不是咱們提供的代碼,依然是運(yùn)行庫(kù)提供的,這也說(shuō)明main函數(shù)不是第一個(gè)執(zhí)行的代碼,它一定是被其它代碼調(diào)用的,main函數(shù)在運(yùn)行庫(kù)代碼初始化完環(huán)境后才被調(diào)用。
咱們繼續(xù)看kernel.bin中的符號(hào),一共就4行,盡管其中也包含了咱們不認(rèn)識(shí)的符號(hào),但畢竟少得多,我們的程序更短小精干,而且確實(shí)沒(méi)有_start函數(shù)。這里添加了3個(gè)類型為A的符號(hào),這表示它們的值是不變的。T表示是該符號(hào)是位于代碼段中,更多符號(hào)的意義請(qǐng)參考man nm。
其實(shí)上述代碼中要是換成匯編代碼的話,就是個(gè)jmp $,其大小不過(guò)是2字節(jié)的機(jī)器碼ebfe。除了編譯器自動(dòng)添加的代碼外,一般情況下c語(yǔ)言編譯出來(lái)的程序也比匯編語(yǔ)言生成的程序體積大。可見,人們常說(shuō)的匯編語(yǔ)言比c語(yǔ)言快,并不是匯編語(yǔ)言本身有多快(它也要變成機(jī)器指令后才能上cpu運(yùn)行),而是匯編語(yǔ)言對(duì)應(yīng)的機(jī)器指令是一對(duì)一,簡(jiǎn)單直接可依賴,而c語(yǔ)言生成的機(jī)器指令是一對(duì)多,復(fù)雜間接略冗余。
好啦,關(guān)于內(nèi)核的部分咱們就此先打住,其實(shí)說(shuō)這話我有點(diǎn)不好意思,您也看到啦,內(nèi)核代碼中就一個(gè)死循環(huán)而已,我們的內(nèi)核還沒(méi)有開始。咱們的內(nèi)核雖然離真正的內(nèi)核差得十萬(wàn)八千里,但它目的是兩個(gè):
后面我們將結(jié)合此簡(jiǎn)單至極的c程序來(lái)學(xué)習(xí)有關(guān)elf方面的知識(shí)。
總結(jié)
以上是生活随笔為你收集整理的一步步编写操作系统 46 用c语言编写内核3的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 又一款高收益稳健理财要消失!想要收益率超
- 下一篇: 惠普FX900固态硬盘上手:主打高性价比