溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

深入理解程序的結(jié)構(gòu)

發(fā)布時(shí)間:2020-06-30 12:06:51 來源:網(wǎng)絡(luò) 閱讀:3174 作者:三九感冒靈 欄目:系統(tǒng)運(yùn)維

深入理解程序的結(jié)構(gòu)

1靜態(tài)可執(zhí)行程序中的段

程序由不同的段構(gòu)成(代碼段、數(shù)據(jù)段),程序的靜態(tài)特征就是指令和數(shù)據(jù),動(dòng)態(tài)特征就是執(zhí)行指令處理數(shù)據(jù)。
源程序代碼到可執(zhí)行程序的對(duì)應(yīng)關(guān)系:
深入理解程序的結(jié)構(gòu)

代碼段

  • 源代碼的可執(zhí)行語句編譯后進(jìn)入代碼段,編譯完成后大小固定
  • 代碼段在內(nèi)存管理單元的系統(tǒng)中具有只讀屬性(是一種保護(hù),防止被改寫)
  • 代碼段中可以包括常量數(shù)據(jù)(如字符串常量)

    數(shù)據(jù)段(.data .bss .rodata)

    .bss段(Block Started by Symbol segment)
    存儲(chǔ)未初始化的全局?jǐn)?shù)據(jù),不占用可執(zhí)行文件的大小。
    .data段:存儲(chǔ)具有非0初始值的變量
    .rodata段:存儲(chǔ)const修飾的和其他只讀數(shù)據(jù)
    問題:.bss和.data段同樣存儲(chǔ)的是全局?jǐn)?shù)據(jù),為什么初始化的和不初始化的保存在不同的段中?
    .bss段中的變量不用在再程序文件中保存初始值,從而減小可執(zhí)程序的大小,提高程序加載的效率。(對(duì)于.bss段中的變量,在可執(zhí)行文件中只需要保存其變量名和變量類型,在加載時(shí)統(tǒng)一將其初始化為0;而對(duì)于存儲(chǔ)于.data段中的數(shù)據(jù),需要保存其變量名,類型、和值,在加載其需要將變量值拷貝得到變量對(duì)應(yīng)的空間)
    編程實(shí)驗(yàn):可以編寫簡(jiǎn)單測(cè)試程序,通過objdump -h命令查看各個(gè)段的信息,使用nm命令查看可執(zhí)行文件中的符號(hào)和地址,使用objdump -s -j .data ./a.ou查看某個(gè)段中的具體信息,并將上述信息對(duì)應(yīng)起來。

    6.2動(dòng)態(tài)加載后生成的段

    棧(stack)

    棧時(shí)在程序被加載到內(nèi)存之后才生成的,其本質(zhì)時(shí)片連續(xù)的存儲(chǔ)空間
    SP寄存器作為棧頂“指針”實(shí)現(xiàn)入棧操作和出棧操作
    深入理解程序的結(jié)構(gòu)
    棧通常作為以下用途
    中斷發(fā)生時(shí),棧用于保存寄存器的值(現(xiàn)場(chǎng)保護(hù))
    函數(shù)調(diào)用時(shí),棧用于保存函數(shù)的活動(dòng)記錄(棧幀信息)
    并發(fā)編程時(shí),每個(gè)線程擁有自己獨(dú)立的棧

    堆(Heap)

    堆和棧一樣,時(shí)程序被加載到內(nèi)存后才生成的。是一片“空閑的空間”,用于提供動(dòng)態(tài)內(nèi)存分配。
    需要函數(shù)的支持(malloc、free)
    內(nèi)存映射段(memory mapping segment)
    內(nèi)核將硬盤中的文件內(nèi)容直接映射到內(nèi)存映射段(mmap)
    動(dòng)態(tài)鏈接庫在可執(zhí)行程序加載時(shí)映射到內(nèi)存映射段
    程序執(zhí)行時(shí)能夠創(chuàng)建匿名映射區(qū)存放程序數(shù)據(jù)
    內(nèi)存映射文件的原理:
    將硬盤上的文件數(shù)據(jù)邏輯映射到內(nèi)存中(零耗時(shí)),通過缺頁中斷進(jìn)行文件數(shù)據(jù)的實(shí)際載入(一次數(shù)據(jù)拷貝),映射后對(duì)內(nèi)存的讀寫就是對(duì)文件的讀寫(極大的提高了文件的讀寫效率)。
    深入理解程序的結(jié)構(gòu)
    使用傳統(tǒng)的方式通過read函數(shù)來讀取文件,首先內(nèi)核程序接到應(yīng)用程的請(qǐng)求,然后內(nèi)核程序去讀取硬盤中的文件內(nèi)核空間,然后再講內(nèi)核空間中的數(shù)據(jù)拷貝到應(yīng)用空間(使用了兩次數(shù)據(jù)拷貝)。
    最終各個(gè)段在內(nèi)存中的布局:
    深入理解程序的結(jié)構(gòu)
    這里我們看到棧、堆的起始地址都是隨機(jī)的,這樣做的目的是為了安全,當(dāng)其實(shí)地址隨機(jī)后,惡意代碼修改程序的暗度變大(難以直接通過固定地址獲取到程度的返回地址)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI