可執行程序的生成:
c語言代碼--->通過編譯器的預處理--->編譯成彙編代碼--->由彙編器編譯成目標代碼--->連接成可執行文件
shell
預處理負責把include的文件包含進來及宏替換等工做函數
以HelloWorld.c文件做爲例子:
操作系統
目標文件:命令行
經常使用的目標文件格式:
3d
PE文件:Windos操做系統
ELF文件:Linux操做系統(可執行,可連接)指針
以ELF文件爲例:(目標文件)blog
默認從0x8048000處開始加載
可執行文件加載到內存中開始執行的第一行代碼
通常靜態連接會將全部代碼放在一個代碼段
動態連接的進程會有多個代碼段進程
可執行程序的執行環境
內存
命令行參數:編譯器
在建立一個新的用戶態堆棧的時候,其實是把命令行參數的內容和環境變量的內容經過指針的方式傳遞到系統調用的內核處理函數的,內核處理函數在建立一個新的可執行堆棧的時候會將命令行參數的內容和環境變量的內容拷貝到用戶態堆棧裏面來初始化新的可執行程序執行的上下文環境
shell程序 -> execve -> sys_execve
先函數調用參數傳遞,在系統調用參數傳遞
動態連接分爲可執行程序裝載時動態連接和運行時動態連接,以下代碼演示了這兩種動態連接。
裝載和啓動一個可執行程序依次調用如下函數:
sys_execve() -> do_execve() -> do_execve_common() -> exec_binprm() -> search_binary_handler() -> load_elf_binary() -> start_thread()
當前進程的正文、數據、堆和棧段被exec覆蓋了,當進程調用一種exec函數時,該進程執行的程序徹底替換爲新程序,而新程序則從其main函數開始執行。 由於調用exec並不建立新進程,因此先後的進程ID並未改變。