您好,登錄后才能下訂單哦!
程序由不同的段構成(代碼段、數據段),程序的靜態特征就是指令和數據,動態特征就是執行指令處理數據。
源程序代碼到可執行程序的對應關系:
.bss段(Block Started by Symbol segment)
存儲未初始化的全局數據,不占用可執行文件的大小。
.data段:存儲具有非0初始值的變量
.rodata段:存儲const修飾的和其他只讀數據
問題:.bss和.data段同樣存儲的是全局數據,為什么初始化的和不初始化的保存在不同的段中?
.bss段中的變量不用在再程序文件中保存初始值,從而減小可執程序的大小,提高程序加載的效率。(對于.bss段中的變量,在可執行文件中只需要保存其變量名和變量類型,在加載時統一將其初始化為0;而對于存儲于.data段中的數據,需要保存其變量名,類型、和值,在加載其需要將變量值拷貝得到變量對應的空間)
編程實驗:可以編寫簡單測試程序,通過objdump -h命令查看各個段的信息,使用nm命令查看可執行文件中的符號和地址,使用objdump -s -j .data ./a.ou查看某個段中的具體信息,并將上述信息對應起來。
棧時在程序被加載到內存之后才生成的,其本質時片連續的存儲空間
SP寄存器作為棧頂“指針”實現入棧操作和出棧操作
棧通常作為以下用途
中斷發生時,棧用于保存寄存器的值(現場保護)
函數調用時,棧用于保存函數的活動記錄(棧幀信息)
并發編程時,每個線程擁有自己獨立的棧
堆和棧一樣,時程序被加載到內存后才生成的。是一片“空閑的空間”,用于提供動態內存分配。
需要函數的支持(malloc、free)
內存映射段(memory mapping segment)
內核將硬盤中的文件內容直接映射到內存映射段(mmap)
動態鏈接庫在可執行程序加載時映射到內存映射段
程序執行時能夠創建匿名映射區存放程序數據
內存映射文件的原理:
將硬盤上的文件數據邏輯映射到內存中(零耗時),通過缺頁中斷進行文件數據的實際載入(一次數據拷貝),映射后對內存的讀寫就是對文件的讀寫(極大的提高了文件的讀寫效率)。
使用傳統的方式通過read函數來讀取文件,首先內核程序接到應用程的請求,然后內核程序去讀取硬盤中的文件內核空間,然后再講內核空間中的數據拷貝到應用空間(使用了兩次數據拷貝)。
最終各個段在內存中的布局:
這里我們看到棧、堆的起始地址都是隨機的,這樣做的目的是為了安全,當其實地址隨機后,惡意代碼修改程序的暗度變大(難以直接通過固定地址獲取到程度的返回地址)。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。