第10章 內(nèi)存

第4部分庫與運行庫

程序的環(huán)境由內(nèi)存、運行庫和系統(tǒng)調(diào)用(API)等構(gòu)成柔昼。

系統(tǒng)調(diào)用和API是程序與內(nèi)核之間交互的中介。

第10章內(nèi)存

10.1程序的內(nèi)存布局

C/C++語言中指針的大小是4個字節(jié)是有原因的,因為指針實際上是個地址值拟淮,地址值決定于內(nèi)存空間大小,而CPU支持的最大內(nèi)存容量是由地址總線的寬度決定的谴忧,因為32位地址總線的寬度是32位很泊,即4字節(jié)角虫,所以指針的大小也是4字節(jié)。

內(nèi)存中有一部分稱為內(nèi)核空間委造,普通的應(yīng)用程序是無法訪問的戳鹅。

除此之外,內(nèi)存還有椈枵祝空間枫虏、堆空間、可執(zhí)行映像亮垫、保留區(qū)模软。

棧:用于維護函數(shù)調(diào)用的上下文。

堆:用于動態(tài)分配空間饮潦,它通常位于棧的下方燃异。

可執(zhí)行映像:用于裝載可執(zhí)行文件在內(nèi)存中的映像。

保留區(qū):內(nèi)存中受保護而禁止訪問的區(qū)域继蜡,如NULL回俐。

內(nèi)存中還有一段動態(tài)鏈接庫映射區(qū),用于裝載動態(tài)鏈接庫稀并。

10.2棧與調(diào)用慣例

10.2.1什么是棧

椊銎模總是向低地址方向增長的。

棧最重要的功能是保存一個函數(shù)調(diào)用所需要的信息碘举,這信息通常被叫做堆棧幀或活動記錄忘瓦。

堆棧幀一般包括:

1、函數(shù)的返回地址和參數(shù)引颈。

2耕皮、臨時變量,包括非晶態(tài)局部變量和編譯期自動生成的臨時變量蝙场。

3凌停、保存的上下文,包括函數(shù)調(diào)用前后需要保持不變的寄存器售滤。

ESP寄存器總是指向棧頂罚拟,EBP(棧指針)寄存器總是指向函數(shù)活動記錄的固定位置。

P313描述了i386函數(shù)調(diào)用的過程完箩。

為什么未初始化的數(shù)組元素被打印出來以后是漢字的“燙”赐俗?

這是因為它們在DEBUG模式下被初始化為0xCC,而兩個連續(xù)的0xCC就是0xCCCC嗜憔,即秃励,漢字的“燙”。

還有的時候是使用0xCD初始化未初始化的數(shù)組吉捶,這時候顯示的漢字是“屯”夺鲜。

“鉤子”函數(shù)可以通過替換掉Windows函數(shù)的匯編序列前面幾條“無用”的指令實現(xiàn)。

10.2.2調(diào)用慣例

是指函數(shù)的調(diào)用方和被調(diào)用方都遵守同樣的函數(shù)調(diào)用方式呐舔。

它一般規(guī)定如下幾個方面的內(nèi)容:

1币励、函數(shù)參數(shù)的傳遞方式和順序。大部分函數(shù)參數(shù)是通過棧傳遞珊拼,有些是通過寄存器食呻。

2、棧的維護方式澎现。就是調(diào)用完了就把被調(diào)方全部彈出棧仅胞。

3、名字修飾策略剑辫。調(diào)用慣例會對函數(shù)本身的名字進行修飾干旧。

_cdecl就是一種調(diào)用慣例。

棧在函數(shù)調(diào)用過程中的變化是這樣的:

1妹蔽、首先將參數(shù)壓入棧中椎眯。

2、繼續(xù)壓入被調(diào)函數(shù)在主調(diào)函數(shù)中的下一條指令的地址胳岂,改地址在內(nèi)存中就是返回地址编整。比如:

現(xiàn)在假設(shè)f是被調(diào)函數(shù),那么return

0的地址就是要被壓入棧中的地址乳丰。

3掌测、跳轉(zhuǎn)到函數(shù)體執(zhí)行。

現(xiàn)在就P322的圖說明幾點問題产园。

old ebp是啥意思汞斧?首先要明確圖中的意思是個值,即ebp寄存器中的值淆两,這個值有著特殊的意義断箫。這個值是個地址,而這個地址是當前函數(shù)的調(diào)用函數(shù)的ebp的值在內(nèi)存中的位置秋冰。所以這就是個無限循環(huán)仲义。

EBP(Extended Base Pointer):擴展基址指針寄存器。

由此可見EBP其實起到了一個基址的作用剑勾,它通常與ESP(Extended

Stack Pointer)搭配使用埃撵,前者是基址,后者是偏移量虽另,這樣的話就可以指向某函數(shù)的寄存器和局部變量了暂刘。

保存這個舊的EBP值的作用在于它能夠恢復(fù)調(diào)用函數(shù)的EBP值,調(diào)用函數(shù)的EBP值是個絕對地址捂刺,如果你不恢復(fù)它谣拣,那么調(diào)用函數(shù)就無法再利用ESP的值來指向它自己的寄存器和全局變量了募寨。

C++中的this指針存放在ECX(Extended

Counter miX,擴展計數(shù)寄存器)中森缠。

10.2.3函數(shù)返回值傳遞

EAX(Extended Accumulator miX拔鹰,擴展累加寄存器)負責(zé)傳遞返回值,它能返回4字節(jié)的返回值贵涵。

對于小于等于8字節(jié)并且大于4字節(jié)的返回值列肢,可以搭配EDX(Extended

Data miX,擴展數(shù)據(jù)寄存器)進行返回宾茂。

如果返回值太大瓷马,那就必須開辟一段棧空間來臨時存放返回值跨晴。首先產(chǎn)生返回值的函數(shù)會把返回值寫到這段空間中欧聘,然后這段空間中的值再寫到真正的用于裝載這個返回值的變量中,這個變量是我們常說的返回值坟奥,至于該段中所說的返回值就是指需要被返回的數(shù)據(jù)树瞭。也就是說在這個過程中會產(chǎn)生兩次復(fù)制。

10.3堆與內(nèi)存管理

堆的處理過程比棧要復(fù)雜爱谁,因為程序在執(zhí)行過程中隨時可能申請空間和釋放空間晒喷,而且申請和釋放的空間大小也不確定。

10.3.1什么是堆

堆是一塊巨大的內(nèi)存空間访敌,占據(jù)了虛擬內(nèi)存的絕大部分凉敲。

堆可以將數(shù)據(jù)傳遞到函數(shù)外面,而且能動態(tài)地產(chǎn)生對象寺旺。

直接操作堆空間的是程序的運行庫爷抓,而不是系統(tǒng)調(diào)用,因為這樣做比較高效阻塑。

10.3.2

Linux進程堆管理

有兩種方式:

1蓝撇、通過調(diào)整數(shù)據(jù)段的結(jié)束地址來調(diào)整堆空間的大小。

2陈莽、直接申請一段內(nèi)存空間用作堆空間渤昌。

申請的空間的起始地址和大小都是頁大小的整數(shù)倍。

在Linux系統(tǒng)下走搁,堆可以存在于從BSS段到共享庫裝載的位置和從共享庫結(jié)束位置到棧這兩部分空間独柑,現(xiàn)在的話能有2.9G大小。也就是說現(xiàn)在你用malloc申請堆空間至多能申請2.9G左右私植。

10.3.3

Windows進程堆管理

Windows下的堆和椉烧ぃ空間是非常零散的,因為每個線程在建立的時候都需要自己的椙冢空間索绪,堆空間就是在剩下的零碎的空間中分配的湖员。

它的對空間大小和起始地址也必須是頁的整數(shù)倍。

無論是Linux還是Windows都有自己的堆分配算法者春。

每個進程在創(chuàng)建的時候破衔,系統(tǒng)都會給它分配一個堆清女,并在進程結(jié)束的時候銷毀堆钱烟。

堆空間并不是連續(xù)的。

堆空間不一定都是向上增長的嫡丙。

10.3.4堆分配算法

它就是負責(zé)管理堆空間的申請拴袭、分配和釋放的算法。

1曙博、空閑鏈表法拥刻。

2、位圖父泳。把整個堆劃分成大小相同的塊般哼,第一個塊叫頭,其余的稱為主體惠窄,用一個數(shù)組來記錄塊的使用情況蒸眠,每個塊有三種狀態(tài),即杆融,頭楞卡、主體和空閑。

3脾歇、對象池蒋腮。如果每次對象申請的堆空間大小相同,就可以把堆劃分成對象大小的若干塊藕各,每次只需要取一塊分配出去即可池摧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市激况,隨后出現(xiàn)的幾起案子作彤,更是在濱河造成了極大的恐慌,老刑警劉巖誉碴,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宦棺,死亡現(xiàn)場離奇詭異,居然都是意外死亡黔帕,警方通過查閱死者的電腦和手機代咸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來成黄,“玉大人呐芥,你說我怎么就攤上這事逻杖。” “怎么了思瘟?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵荸百,是天一觀的道長。 經(jīng)常有香客問我滨攻,道長够话,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任光绕,我火速辦了婚禮女嘲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诞帐。我一直安慰自己欣尼,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布停蕉。 她就那樣靜靜地躺著愕鼓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慧起。 梳的紋絲不亂的頭發(fā)上菇晃,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音完慧,去河邊找鬼谋旦。 笑死,一個胖子當著我的面吹牛屈尼,可吹牛的內(nèi)容都是我干的册着。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼脾歧,長吁一口氣:“原來是場噩夢啊……” “哼甲捏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鞭执,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤司顿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后兄纺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體大溜,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年估脆,在試婚紗的時候發(fā)現(xiàn)自己被綠了钦奋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖付材,靈堂內(nèi)的尸體忽然破棺而出朦拖,到底是詐尸還是另有隱情,我是刑警寧澤厌衔,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布璧帝,位于F島的核電站,受9級特大地震影響富寿,放射性物質(zhì)發(fā)生泄漏睬隶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一作喘、第九天 我趴在偏房一處隱蔽的房頂上張望理疙。 院中可真熱鬧,春花似錦泞坦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滤蝠,卻和暖如春豌熄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背物咳。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工锣险, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人览闰。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓芯肤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親压鉴。 傳聞我的和親對象是個殘疾皇子崖咨,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容