區域性靜態變數的初始化觀測
//全域性變數
int global=0x11111;
int main(int argc, char* argv[])
{
//區域性變數
int temp=0x160;
global=global+temp;
return 0;
}
6: int global=0x111111;
7: int main(int argc, char* argv[])
8: {
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,44h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-44h]
0040101C mov ecx,11h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
9: //區域性變數
10: int temp=0x160;
00401028 mov dword ptr [ebp-4],160h
11:
12: global=global+temp;
0040102F mov eax,[global (00428a64)]
00401034 add eax,dword ptr [ebp-4]
00401037 mov [global (00428a64)],eax
13:
14: return 0;
0040103C xor eax,eax
15: }
0040103E pop edi
0040103F pop esi
00401040 pop ebx
00401041 mov esp,ebp
00401043 pop ebp
00401044 ret
可以查詢到0040102F mov eax,[global (00428a64)]
我們可以很清楚地看到區域性變數是直接儲存在[ebp-4]也就是堆疊中的而全域性變數則是儲存在一個固定的記憶體地址00428a64裡,同時在斷點剛斷下的時候,就是還沒執行上面的程式碼時,觀察[global (00428a64)]也就是全域性變數地址裡儲存的內容時,可以看到我們全域性變數已經初始化並被賦值了,觀察整個main函式的反彙編程式碼,我們並沒有看到全域性變數賦值相關的語句,但這並不能說明程式在執行前就已經賦值了,別忘了也有可能是在mainCRTStartup中將這裡初始化的,一開啟程式全域性變數就已經初始化了。
靜態區域性變數和全域性變數一樣,資料都存放在全域性區域,所以在主程式之前,編譯器已經為其分配好了記憶體,但在C和C++中靜態區域性變數的初始化節點又有點不太一樣。在C中,初始化發生在程式碼執行之前,編譯階段分配好記憶體之後,就會進行初始化,所以我們看到在C語言中無法使用變數對靜態區域性變數進行初始化,在程式執行結束,變數所處的全域性記憶體會被全部回收。而在C++中,初始化時在執行相關程式碼時才會進行初始化,主要是由於C++引入物件後,要進行初始化必須執行相應建構函式和解構函式,在建構函式或解構函式中經常會需要進行某些程式中需要進行的特定操作,並非簡單地分配記憶體。所以C++標準定為全域性或靜態物件是有首次用到時才會進行構造,並透過atexit()來管理。在程式結束,按照構造順序反方向進行逐個析構。所以在C++中是可以使用變數