我們看下面的例子: /* file name test00.c */ int main(int argc, char* argv) { return 0; } 編譯連結它: cc test00.c -o test.exe 會生成 test.exe 但是我們加上這個選項: -nostdlib (不連結標準庫) cc test00.c -nostdlib -o test.exe 連結器會報錯: undefined symbol: __start 也就是說:
1. 編譯器預設是找 __start 符號,而不是 main
2. __start 這個符號是程式的起始點
3. main 是被標準庫呼叫的一個符號通常,我們會在編譯器的環境中找到一個名字類似於 crt0.o 的檔案,這個檔案中包含了我們剛才所說的 __start 符號。那麼真正的 crt0.s 是什麼樣子呢?下面我們給出部分虛擬碼: /////////////////////////////////////////////////////// section .text: __start: : init stack; init heap; open stdin; open stdout; open stderr; : push argv; push argc; call _main; (呼叫 main) : destory heap; close stdin; close stdout; close stderr; : call __exit; ////////////////////////////////////////////////////總結:main函式執行之前,主要就是初始化系統相關資源:1.設定棧指標2.初始化static靜態和global全域性變數,即data段的內容3.將未初始化部分的賦初值:數值型short,int,long等為0,bool為FALSE,指標為NULL,等等,即.bss段的內容4.執行全域性構造器,估計是C++中建構函式之類的吧5.將main函式的引數,argc,argv等傳遞給main函式,然後才真正執行main函式main 函式之後會執行相反的工作。
我們看下面的例子: /* file name test00.c */ int main(int argc, char* argv) { return 0; } 編譯連結它: cc test00.c -o test.exe 會生成 test.exe 但是我們加上這個選項: -nostdlib (不連結標準庫) cc test00.c -nostdlib -o test.exe 連結器會報錯: undefined symbol: __start 也就是說:
1. 編譯器預設是找 __start 符號,而不是 main
2. __start 這個符號是程式的起始點
3. main 是被標準庫呼叫的一個符號通常,我們會在編譯器的環境中找到一個名字類似於 crt0.o 的檔案,這個檔案中包含了我們剛才所說的 __start 符號。那麼真正的 crt0.s 是什麼樣子呢?下面我們給出部分虛擬碼: /////////////////////////////////////////////////////// section .text: __start: : init stack; init heap; open stdin; open stdout; open stderr; : push argv; push argc; call _main; (呼叫 main) : destory heap; close stdin; close stdout; close stderr; : call __exit; ////////////////////////////////////////////////////總結:main函式執行之前,主要就是初始化系統相關資源:1.設定棧指標2.初始化static靜態和global全域性變數,即data段的內容3.將未初始化部分的賦初值:數值型short,int,long等為0,bool為FALSE,指標為NULL,等等,即.bss段的內容4.執行全域性構造器,估計是C++中建構函式之類的吧5.將main函式的引數,argc,argv等傳遞給main函式,然後才真正執行main函式main 函式之後會執行相反的工作。