1. 程式人生 > >【軟體開發底層知識修煉】十 連結器-main函式不是第一個被執行的函式

【軟體開發底層知識修煉】十 連結器-main函式不是第一個被執行的函式

上一篇文章,大概瞭解了連結器的工作內容就是:符號解析和重定位。點選上一篇文章檢視:點選檢視

本片文章其實還是圍繞連結器來學習。只不過不是很明顯,當你學到下一篇文章時,就明白了。

本篇文章來弄明白一個問題:在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