【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数
上一篇文章,大概了解了鏈接器的工作內(nèi)容就是:符號(hào)解析和重定位。點(diǎn)擊上一篇文章查看:點(diǎn)擊查看。
本片文章其實(shí)還是圍繞鏈接器來學(xué)習(xí)。只不過不是很明顯,當(dāng)你學(xué)到下一篇文章時(shí),就明白了。
本篇文章來弄明白一個(gè)問題:在C/C++程序被加載到內(nèi)存中準(zhǔn)備運(yùn)行時(shí),main函數(shù)是第一個(gè)被執(zhí)行的函數(shù)么?答案肯定不是!如果是,就沒必要去寫這個(gè)文章了!!!
1、_start()函數(shù)
先說結(jié)果:_start() 是第一個(gè)被執(zhí)行的函數(shù),而不是main()函數(shù)。
我們的程序中并沒有寫_start() ,它是通過鏈接器鏈接到可執(zhí)行文件中的(下一篇文章可以學(xué)習(xí)到這是如何辦到的)。
在默認(rèn)情況下(gcc)
- 程序加載后,_start()是第一個(gè)被執(zhí)行的函數(shù)
- _start()函數(shù),準(zhǔn)備好參數(shù)后,立即調(diào)用 __libc_start_main() 函數(shù)
- __libc_start_main() 初始化運(yùn)行環(huán)境后,調(diào)用main()函數(shù)執(zhí)行
注意:_start()函數(shù)的入口地址就是代碼段(.text)的起始地址
2、__libc_start_main()函數(shù)的作用
__lib_start_main()函數(shù)的作用
- 調(diào)用__libc_csu_init()函數(shù)(完成必要的初始化操作)
- 啟動(dòng)程序的第一個(gè)線程(主線程),main()函數(shù)為主線程入口
- 注冊(cè)__libc_csu_fini()函數(shù)(程序運(yùn)行終止時(shí)被調(diào)用)
3、程序的啟動(dòng)過程
下面給一個(gè)簡圖,來說明一個(gè)C/C++程序的執(zhí)行過程:
4、自定義程序的入口函數(shù)
- gcc 提供-e選項(xiàng),用于在鏈接時(shí)指定入口函數(shù)
- 自定義入口函數(shù)時(shí),必須使用選項(xiàng) -nostartfiles 進(jìn)行鏈接
比如以下程序:
program.c
#include <stdio.h> #include <stdlib.h>int program() {printf("D.T.Software\n");exit(0); }很明顯它沒有main函數(shù)。但是我們通過以下編譯命令進(jìn)行編譯:
- gcc -e program -nostartfiles program.c -o program
生成可執(zhí)行文件 program
運(yùn)行該可執(zhí)行文件: ./program
可以得到運(yùn)行結(jié)果:
顯而易見,我們改變了程序的入口函數(shù)。雖然沒有寫main函數(shù),但是依然可以運(yùn)行該程序!!!
5、總結(jié)
本文主要是理解程序的入口函數(shù)。最好自己私底下做實(shí)驗(yàn),看一下可執(zhí)行文件的反匯編代碼,就知道整個(gè)程序的執(zhí)行流程了。
本文參考狄泰軟件學(xué)院相關(guān)課程
想學(xué)習(xí)的可以加狄泰軟件學(xué)院群,
群聊號(hào)碼:199546072
學(xué)習(xí)探討加個(gè)人(可以免費(fèi)幫忙下載CSDN資源):
qq:1126137994
微信:liu1126137994
總結(jié)
以上是生活随笔為你收集整理的【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++11系列学习之五-------de
- 下一篇: python 记录