操做系統裝載程序以後,首先運行的代碼並非main的第一行,而是某些別的代碼,這些代碼負責準備好main函數執行所須要的環境,而且負責調用main函數, 運行這些代碼的函數稱爲入口函數或入口點(Entry Point),視平臺的不一樣而有不一樣的名字。程序的入口點其實是一個程序的初始化和結束部分,它每每是運行庫的一部分。數組
a. 操做系統在建立進程後,把控制權交到了程序的入口,這個入口每每是運行庫中的某個入口函數。
b. 入口函數對運行庫和程序運行環境進行初始化,包括堆、I/O、線程、全局變量構造,等等。
c. 入口函數在完成初始化以後,調用main函數,正式開始執行程序主體部分。
d. main函數執行完畢之後,返回到入口函數,入口函數進行清理工做,包括全局變量析構、堆銷燬、關閉I/O等,而後進行系統調用結束進程。數據結構
MSVC的CRT默認的入口函數名爲 mainCRTStartup函數
if ( !_heap_init(0) ) { fast_error_exit(_RT_HEAPINIT); } - 這裏使用_heap_init函數對堆(heap)進行了初始化,若是堆初始化失敗,那 麼程序就直接退出了。 - 它僅僅調用了HeapCreate的API建立了一個系統堆,那麼MSVC的malloc其實 也是調用這個API將堆管理過程交給系統
使用_ioinit函數初始化了I/O,接下來這段代碼調用了一系列函數進行各類初始化,包括:操作系統
FILE結構體命令行
struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE; - 這個FILE結構中最重要的一個字段是_file,_file是一個整數,經過_file能夠訪問到內部文件句柄表中的某一項。在Windows中,用戶態使用句柄(Handle)來訪問內核文件對象,句柄自己是一個32位的數據類型,在有些場合使用int來儲存,有些場合使用指針來表示。
在MSVC的CRT中,已經打開的文件句柄的信息使用數據結構ioinfo來表示:線程
typedef struct { intptr_t osfhnd; char osfile; char pipech; } ioinfo; □ 在這個結構中,osfhnd字段即爲打開文件的句柄,這裏使用8字節整數類型intptr_t來存儲。另外osfile的意義爲文件的打開屬性。而pipech字段則爲用於管道的單字符緩衝,這裏能夠先忽略。 □ 在crt/src/ioinit/c中有一個數組-------ioinfo *_pioinfo[64]; //等效於 ioinfo _pioinfo[64][32] □ 二維上可容納32個ioinfo結構,所以該表可容納64 * 32 = 2048 個句柄 □ 而FILE中_file的值就是和上面的osfhnd直接關聯 ® _file中第五位到第十位是一維座標 ® _file中第零位到第四位是二維座標 □ 應用程序能夠經過API GetStartupInfo來繼承打開的文件
e. 整體步驟指針
1. 初始化和OS版本有關的全局變量。 2. 初始化堆。 3. 初始化I/O。 4. 獲取命令行參數和環境變量。 5. 初始化C庫的一些數據。 6. 調用main並記錄返回值。 7. 檢查錯誤並將main的返回值返回。