不對,如下代碼:

#include &

static int x = []()
{
std::cout &

輸出:

Performs before main function
Performs inside main function


肯定不是從main開始執行的,一個進程啟動過程是很複雜的,有些是OS機制決定的(比如ELF載入,動態庫載入,和棧結構建立)和語言機制決定的(比如全局對象的構造函數),我下面將Linux啟動一個ELF進程的關鍵過程列出來:

1、可執行文件載入到內存上(Linux kernel乾的事情)

2、跳到動態鏈接器執行(動態鏈接器乾的事情):

2.1:將該可執行文件依賴的動態鏈接庫全部載入到內存上

2.2 : 完成載入動態庫的「數據依賴類型」的重定位工作(函數調用類的重定位,一般採用GOT/PLT機制實現延遲綁定,啟動過程不做這類的重定位工作)

3、跳到可執行文件的入口地址(entry point) 開始執行(實際上是glibc提供的crtn.o)

3.1 構建執行堆棧

3.2 構建命令行參數和環境變數參數表(即main函數 int main(int argc, char *argv[], char *env[]) 的這幾個參數表

3.3 調用可執文件和各動態庫的構建函數

4.、跳到main函數執行

只有3.3和4這兩步是跟編寫的代碼相關,之前的步驟都是運行環境相關的事情。上述是關鍵過程,沒有翻代碼來寫,所以肯定存在錯誤,還請大家海涵。


有些程序跑的是不帶操作系統的,你讓它從fuck()開始也行


鏈接程序可以指定入口,比如ld命令的參數e,後面跟著你指定的入口


腳本語言了解一下


不是,一般會先啟動對應語言的運行時。比如你是C++寫的就會先啟動C++的運行時。

等它完成初始化以後,它再去啟動你自己程序的入口點。這個一般是你在編譯項目的時候配置的,默認是main函數。當然你也可以指定成別的函數。

實際上不同的系統都有默認的規定。系統在啟動你的程序的時候,它會先把你的文件載入到內存離,不管你是Windows還是Linux。完成一系列的初始化操作以後,再去找默認的入口指令去執行。一般而言這個入口指令都是屬於運行時的,等它完成初始化以後才會去進入你自己代碼的入口。


推薦閱讀:
相关文章