【軟體開發底層知識修煉】十 連結器-main函式不是第一個被執行的函式
阿新 • • 發佈:2018-12-12
上一篇文章,大概瞭解了連結器的工作內容就是:符號解析和重定位。點選上一篇文章檢視:點選檢視。
本片文章其實還是圍繞連結器來學習。只不過不是很明顯,當你學到下一篇文章時,就明白了。
本篇文章來弄明白一個問題:在C/C++程式被載入到記憶體中準備執行時,main函式是第一個被執行的函式麼?答案肯定不是!如果是,就沒必要去寫這個文章了!!!
1、_start()函式
先說結果:_start() 是第一個被執行的函式,而不是main()函式。
我們的程式中並沒有寫_start() ,它是通過連結器連結到可執行檔案中的(下一篇文章可以學習到這是如何辦到的)。
在預設情況下(gcc)
- 程式載入後,_start()是第一個被執行的函式
- _start()函式,準備好引數後,立即呼叫 __libc_start_main() 函式
- __libc_start_main() 初始化執行環境後,呼叫main()函式執行
注意:_start()函式的入口地址就是程式碼段(.text)的起始地址
2、__libc_start_main()函式的作用
__lib_start_main()函式的作用
- 呼叫__libc_csu_init()函式(完成必要的初始化操作)
- 啟動程式的第一個執行緒(主執行緒),main()函式為主執行緒入口
- 註冊__libc_csu_fini()函式(程式執行終止時被呼叫)
3、程式的啟動過程
下面給一個簡圖,來說明一個C/C++程式的執行過程:
4、自定義程式的入口函式
- gcc 提供
-e
選項,用於在連結時指定入口函式 - 自定義入口函式時,必須使用選項
-nostartfiles
進行連結
比如以下程式:
program.c
#include <stdio.h>
#include <stdlib.h>
int program()
{
printf("D.T.Software\n");
exit(0);
}
很明顯它沒有main函式。但是我們通過以下編譯命令進行編譯:
- gcc -e program -nostartfiles program.c -o program
生成可執行檔案 program
執行該可執行檔案: ./program
可以得到執行結果:
顯而易見,我們改變了程式的入口函式。雖然沒有寫main函式,但是依然可以執行該程式!!!
5、總結
本文主要是理解程式的入口函式。最好自己私底下做實驗,看一下可執行檔案的反彙編程式碼,就知道整個程式的執行流程了。
本文參考狄泰軟體學院相關課程
想學習的可以加狄泰軟體學院群,
群聊號碼:199546072
學習探討加個人(可以免費幫忙下載CSDN資源):
qq:1126137994
微信:liu1126137994