__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;
int main(int argc, char *argv[])
// argc:參數個數; argv:參數字符串數組
1. 調用main函數之前,
-
創建進程後,把控制權交給程序的入口函數,即爲運行時庫的某個入口函數。
-
glibc的入口函數是_start
-
msvc(vc 6.0)的是mainCRTStartup
-
-
入口函數對運行庫和運行環境進行初始化,包括堆、I/O、線程、全局變量構造
-
初始化堆,棧(設置棧指針)
-
全局變量、對象和靜態變量、對象的空間分配和初始化。
-
初始化C/C++庫
-
參數壓棧 argc,argv ,獲取環境變量
-
打開標準輸入,輸出、錯誤流
-
-
註冊析構函數,使用atexit註冊析構函數(註冊時在鏈表頭插入鏈接,main函數退出也從鏈表頭開始獲取鏈表函數,進行調用)
2. 調用main函數之後,
- 返回入口函數,進行清理工作
- 包括全局變量析構、堆銷燬、關閉I/O
-
銷燬堆內存
-
關閉標準輸入、輸出、關閉錯誤流
-
-
調用exit系統API退出進程
3. 如何在main()函數之前執行一條語句?
(1)在C++中,可通過全局變量的構造函數執行
(2)全局變量的賦值函數
(3)指定入口點,入口點中調用原來的入口點。
4. 用於註冊終止函數
- atexit()
int atexit(void (*func)(void))
c庫中的atexit()函數,當程序正常中止時,調用指定的func函數。當然,你可以在任何地方註冊終止函數,但它會在程序終止的時候被調用。
(終止函數func不接受任何參數)
- _onexit()
4. printf函數是調用stdout指針在屏幕上輸出。
#define printf(args...) fprintf(stdout, ##args)
5. 運行時庫的主要功能
-
啓動與退出,包括入口函數及其依賴函數
-
標準函數
-
I/O,I/O功能的封裝和實現,如提供PRINT
-
堆,堆的封裝與實現
-
調試支持