[轉組第8天] | 變量在內存中的位置和訪問方式
2018-05-05
《C++反匯編和逆向技術》第七章 變量在內存中的位置和訪問方式 讀書筆記
1.全局變量和局部變量的區別
全局變量屬於進程作用域,也就是說,在整個進程中都能夠訪問到這個全局變量。靜態變量屬於文件作用域,在當前源碼文件內可以訪問到;局部變量屬於函數作用域,在函數內部可以訪問到;在“{}”語句塊內定義的變量,屬於塊作用域,只能在定義變量的“{}"快內訪問到。
全局變量在內存中的地支順序是先定義的變量在低地址,後定義的變量在高地址。
全局變量的特征如下:
* 所在地址為數據區,生命周期與所在模塊一致;
* 使用立即數間接訪問。//[g_nVar]
局部變量的特征如下:
* 所在地址為棧區,生命周期與所在的函數作用域一致;
* 使用ebp或esp間接訪問。
2. 局部靜態變量的工作方式
靜態變量分為全局靜態變量和局部靜態變量,全局靜態變量和全局變量類似,只是全局靜態變量只能在本文件內使用。但這只是在編譯之前的語法檢查過程中,對訪問外部的全局靜態變量做出的限制。全局靜態變量的生命周期和全局變量也是一樣的,而且在反匯編代碼中它們也無二樣。
局部靜態變量比較特殊,它不會隨作用域的結束而消失,並且在未進入作用域之前就已經存在,其生命周期也和全局變量相同。局部靜態常量會被預先被作為全局變量處理,而它的初始化部分只是在做賦值操作而已。
局部靜態變量只初始化一次,因為其有一個標誌位,如果為0則賦值初始化,否則賦值。標誌位大小為1個字節,可以表示8個局部靜態變量的狀態。
如果初始化的數值為常量,即多次初始化也不會產生變化,編譯器就直接采用全局變量方式處理,優化了代碼,提升了效率。為了使其不超出作用域訪問,使用名稱粉碎法,在編譯期將靜態變量重新命名,在原有名稱中加入其所在作用域以及類型等信息。
3. 堆變量
malloc與new實現堆空間的申請。
free與delete完成對空間釋放。
堆空間的分配類似於商場中的商鋪管理,malloc是從商場的空地中劃分出一塊作為商鋪,而new則可以將劃分好的商鋪直接租用。由於malloc缺少商鋪的營業範圍規定,因此需要將申請好的堆強制轉換以說明其類型方可使用,而new則無需這種操作,直接可以使用。
在對數據末尾也加入了0xFDFDFDFD,這是向下越界的檢查標誌,這是程序編譯方式為Debug版的重要特征之一。
[轉組第8天] | 變量在內存中的位置和訪問方式