您好,登錄后才能下訂單哦!
我們在上節中說到了棧區、堆區以及靜態存儲區,那么我們來看看在程序文件的一般布局。我們先來看看不同代碼在可執行程序中的對應關系,如下圖所示
我們看到程序中的經過初始化的全局變量和加 static 修飾的初始化過后的局部變量都放在 .data 段,未經初始化的全局變量和加 static 修飾的局部變量都放在 .bss 段,函數和函數調用都放在 .text 段。
我們下來看看程序和進程的區別,程序是靜態的概念表現為一個可執行文件,而進程是動圖的概念,程序由操作系統加載運行后得到進程。每個程序可以對應多個進程,但是每個進程只能對應一個程序。我們舉例來說,一個瀏覽器就相當于是程序,它沒運行就沒有對應的進程。但是我們可以同時多次打開同一個瀏覽器,這時每個打開的瀏覽器就相當于是一個進程。
我們在面試中有時會遇到這樣的問題:包含腳本代碼的文本文件是一種類型的可執行程序嗎?如果是,它對應什么樣的進程呢?我們想的是腳本程序嘛,就肯定能直接運行哈,那它會對應什么樣的進程呢?不知所云了。哈哈,我們來看看一般的可執行程序和腳本文件的區別,如下圖所示
我們看到可執行程序是由操作系統直接加載的,便直接對應了一個進程。但是我們運行腳本文件之后,那么操作系統中會有對應的腳本解釋程序,經腳本解釋程序執行后,便產生對應的進程,這個進程反過來讀取并解釋執行腳本。這樣腳本文件就得到運行啦。
下來我們來看看文件布局在內存中的映射
我們看到可執行程序 a.out 中分為頭文件、.text、.data 以及 .bss 段。對應在進程中便去掉了頭文件而加上了棧和堆。那么我們接下來講講各個段的作用,堆棧段在程序運行后才正式存在,是程序運行的基礎; .bss 段存放的是未初始化的全局變量和靜態變量; .text 段存放的是程序中的可執行代碼; .data 段保存的是已經初始化了的全局變量和靜態變量; .rodata 段存放程序中的常量值,如字符串常量。
靜態存儲區通常指程序中的 .bss 和 .data 段;只讀存儲區通常指程序中的 .rodata 段;局部變量所占空間為棧上的空間;動態空間為堆中的空間;程序可執行代碼存放于 .text 段。
那么我們想下,同是全局變量和靜態變量,為什么初始化的和未初始化的需要保存在不同段中呢?通常在編譯器中,沒有初始化的變量,我們都要初始化為 0,如果我們一個一個的去檢查,是不是效率就很低呢?如果我們分開存放,那么那些已經初始化過的變量就不用去檢查了,從而效率會變高。
通過對程序文件中內存布局的學習,總結如下:1、程序源碼在編譯后對應可執行程序中的不同存儲區;2、程序和進程不同,程序是靜態概念,進程是動圖概念;3、堆棧段是程序運行的基礎,只存在于進程空間中;4、程序可執行代碼存放于 .text 段,是只讀的;5、.bss 和 .data 段用于保存全局變量和靜態變量。
歡迎大家一起來學習 C 語言,可以加我QQ:243343083。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。