最近復習《深入理解計算機系統》,參考了小土刀的博客,看到了進程和程序在內存中是如何組織的,雖然這張圖看了很多遍但是總感覺有疑問。努力解決,參考《深入理解計算機系統》。
關於程序和進程區別的概念
- 程序是指令和數據的集合,可以作為目標文件保存在磁盤中,或者作為段存放在內存地址空間中。
- 進程是程序運行的一個具體的實例,程序總是運行在某個進程的上下文中。
C 程序到可執行程序
圖1 C程序的編譯過程
如上圖一個 C 語言程序需要經過預處理、編譯器、匯編器、鏈接器 才可以生成一個可執行文件(程序)。
hello.s 匯編代碼使用匯編器生成可重定位目標文件 hello.o。
hello.o 和它 引入的類庫 printf.o 使用鏈接器生成可執行程序。下圖可執行文件的存儲格式示例
可執行文件的執行過程
當在 Shell 實行 ./hello 時,Shell 認為 hello 是一個可執行文件,於是調用駐留在存儲器中稱為加載器(loader)的操作系統代碼來運行它。 加載器將可執行目標文件的代碼和數據從磁盤讀到內存,然后通過跳轉到程序的第一條指令或者入口點來運行程序。
通過 shell 執行過程簡單介紹
shell 執行一個程序時,父 shell 進程生成一個子進程,他是父進程的一個復制。子進程通過 execve 系統調用加載器。加載器刪除子進程的虛擬內存段,並創建新的代碼、數據、堆和棧段。通過將虛擬地址的頁地址映射到內存中可執行文件的頁地址來初始化可執行文件的內容。最后,加載器跳轉到 _start 地址,調用程序的 main 函數。
通過上面的描述可以理解到為什么 “程序總是運行在某個進程的上下文中”。
概括
- 可執行文件加載入內存(可執行文件在內存中的內存映像順序存儲)
- 開辟進程進行虛擬內存地址的重定向
- 執行
了解了可執行文件的存儲格式,加載一個可執行文件到初始化一個進程,但是總感覺有很多疑惑沒有解開.......