【彙編】C++ 函數調用之——局部變量。

咱們知道,棧做爲一種數據結構,是一種只能在一端進行插入和刪除操做的特殊線性表。它按照後進先出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,須要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。 數據結構

C++函數內的參數和局部變量都是存放在棧空間內,那麼具體是如何存放和利用的呢?讓咱們來一探究竟。 app

有以下測試代碼: 函數

void func(){
	int a;
	char b;
	double c;

	a=97;
	b=a;
	c=7.2;
}


int main(int argc,char *argv[])
{
	//call func
	func();
	return 0;
}
func函數內有三個類型不相同的變量a,b,c 而後對a,b,c分別賦值。

對應的彙編碼大體以下: 測試

void func(){
00B013D0  push        ebp  
00B013D1  mov         ebp,esp  
00B013D3  sub         esp,0E8h  
00B013D9  push        ebx  
00B013DA  push        esi  
00B013DB  push        edi  
00B013DC  lea         edi,[ebp+FFFFFF18h]  
00B013E2  mov         ecx,3Ah  
00B013E7  mov         eax,0CCCCCCCCh  
00B013EC  rep stos    dword ptr es:[edi]  
//上面的指令意思一樣是分配棧空間,只不過大小變成了3A*4=E8(232)字節
//若是沒有這三個局部變量和參數,那麼分配的空間應該是192字節,232-192=40,
//也就是說多分配了40字節
	int a;
	char b;
	double c;
//a,b,c在棧中的位置以下圖所示,從彙編也能夠看到:
//&a = ebp-8h
//&b = ebp-11h
//&c = ebp-24h
//好像並非想像中的那樣相鄰存放的,可是依然符合棧的存放特色:從高地址往低地址
	a=97;
00B013EE  mov         dword ptr [ebp-8],61h  
	b=a;
00B013F5  mov         al,byte ptr [ebp-8]  
00B013F8  mov         byte ptr [ebp-11h],al  
	c=7.2;
//這裏存7.2的時候是從前面某個內存區域經過雙字傳送指令實現的,
//C語言中7.2默認是double(64位8字節)是一個32位寄存器存放不了的,
//所以須要在編譯期先放到內存裏面,而後拷貝到棧內
00B013FB  movsd       xmm0,mmword ptr ds:[00B058A8h]  
00B01403  movsd       mmword ptr [ebp-24h],xmm0  
}
00B01408  pop         edi  
00B01409  pop         esi  
00B0140A  pop         ebx  
00B0140B  mov         esp,ebp  
00B0140D  pop         ebp  
00B0140E  ret  
--- 無源文件 -----------------------------------------------------------------------
00B0140F  int         3  
00B01410  int         3  
00B01411  int         3  
00B01412  int         3  
00B01413  int         3  
00B01414  int         3  
00B01415  int         3  
00B01416  int         3  
00B01417  int         3  
00B01418  int         3  
00B01419  int         3  
00B0141A  int         3  
00B0141B  int         3  
00B0141C  int         3  
00B0141D  int         3  
00B0141E  int         3  
00B0141F  int         3  
00B01420  int         3  
00B01421  int         3  
00B01422  int         3  
00B01423  int         3  
00B01424  int         3  
00B01425  int         3  
00B01426  int         3  
00B01427  int         3  
00B01428  int         3  
00B01429  int         3  
00B0142A  int         3  
00B0142B  int         3  
00B0142C  int         3  
00B0142D  int         3  
00B0142E  int         3  
00B0142F  int         3  
--- f:\cpp\clr\consoleapplication1\源.cpp ---------------------------------------


int main(int argc,char *argv[])
{
00B01430  push        ebp  
00B01431  mov         ebp,esp  
00B01433  sub         esp,0C0h  
00B01439  push        ebx  
00B0143A  push        esi  
00B0143B  push        edi  
00B0143C  lea         edi,[ebp+FFFFFF40h]  
00B01442  mov         ecx,30h  
00B01447  mov         eax,0CCCCCCCCh  
00B0144C  rep stos    dword ptr es:[edi]  
	//call func
	func();
00B0144E  call        00B01082  
	return 0;
00B01453  xor         eax,eax  
}
00B01455  pop         edi  
00B01456  pop         esi  
00B01457  pop         ebx  
00B01458  add         esp,0C0h  
00B0145E  cmp         ebp,esp  
00B01460  call        00B01140  
00B01465  mov         esp,ebp  
00B01467  pop         ebp  
00B01468  ret

func函數棧區內存分佈: 編碼

其中紅框部分是變量a被賦值以前, code

如今a被賦值爲十進制的97,換成16進制就是 0x0000 0061,和下圖一致,注意存放規則!
高八位存0000,低八位存0061 內存

如今a,b,c都被賦值: io

能夠看到佔用狀況: console

a是int 佔4字節;b是char佔1字節;c是double佔8字節;且a,b,c並未連續存放 編譯

相關文章
相關標籤/搜索