main函數前後做了什麼

__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

  • 堆,堆的封裝與實現

  • 調試支持

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章