1. 程式人生 > >彙編看函式呼叫過程

彙編看函式呼叫過程

分析下列原始碼

#include <windows.h>

DWORD _stdcall Function(DWORD dwP1, PVOID p2)
{
	DWORD v1;
	DWORD v2 = 3;
	v1 = dwP1 + v2;
	return v1;
}

int  main()
{
	Function(100,nullptr);
	return 0;
}

轉匯編  vs2012

#include <windows.h>  
  
DWORD _stdcall Function(DWORD dwP1, PVOID p2)  
{  
00FE13D0  push        ebp    		//ebp = 003EFDCC
00FE13D1  mov         ebp,esp    	//ebp = esp = 003EFCF0
00FE13D3  sub         esp,0D8h		//esp = esp -512=003EFC18  擴充512位元組   
00FE13D9  push        ebx   		//ebx = 7EFDE000
00FE13DA  push        esi    		//esi = 00000000
00FE13DB  push        edi   		//edi = 003EFDCC
00FE13DC  lea         edi,[ebp-0D8h]//edi = 003EFC18  
00FE13E2  mov         ecx,36h		//ecx = 36h
00FE13E7  mov         eax,0CCCCCCCCh//eax = 0CCCCCCCCh  
//rep重複其上面的指令,ECX的值是重複的次數.  
    
//stos將eax中的值拷貝到ES:EDI指向的地址(4位元組dword).   ecx值隨著拷貝次數減少  
//如果設定了direction flag, 那麼edi會在該指令執行後減小, 如果沒有設定direction flag, 那麼edi的值會增加, 這是為了下一次的儲存做準備.  
00FE13EC  rep stos    dword ptr es:[edi]//即從記憶體003EFC18-003EFCEC值都為0CCCCCCCCh  
    DWORD v1;  
	DWORD v2 = 3;  

//00FE13EE  mov         dword ptr [ebp-14h],3    
00FE13EE  mov         dword ptr [v2],3    
	v1 = dwP1 + v2;  
//00FE13F5  mov         eax,dword ptr [ebp+8]    
00FE13F5  mov         eax,dword ptr [dwP1]  
//00FE13F8  add         eax,dword ptr [ebp-14h]   
00FE13F8  add         eax,dword ptr [v2]    
//00FE13FB  mov         dword ptr [ebp-8],eax    
00FE13FB  mov         dword ptr [v1],eax    
	return v1;  
//00FE13FE  mov         eax,dword ptr [ebp-8]   
00FE13FE  mov         eax,dword ptr [v1]    
}  
00FE1401  pop         edi    	//edi = 003EFDCC 
00FE1402  pop         esi    	//esi = 00000000
00FE1403  pop         ebx    	//ebx = 7EFDE000
00FE1404  mov         esp,ebp   //esp = ebp = 003EFCF0
00FE1406  pop         ebp    	//ebp = 003EFDCC
00FE1407  ret         8//因為_stdcall 所以由被呼叫者平衡棧  +8  
  
  
-----------------------------------------  
int  main()  
{  
00FE1420  push        ebp    
00FE1421  mov         ebp,esp    
00FE1423  sub         esp,0C0h    
00FE1429  push        ebx    
00FE142A  push        esi    
00FE142B  push        edi    
00FE142C  lea         edi,[ebp+FFFFFF40h]    
00FE1432  mov         ecx,30h    
00FE1437  mov         eax,0CCCCCCCCh    
00FE143C  rep stos    dword ptr es:[edi]    
    Function(100,nullptr);  
00FE143E  push        0    
00FE1440  push        64h    
00FE1442  call        00FE11EA    
    return 0;  
00FE1447  xor         eax,eax    
}  
00FE1449  pop         edi    
}  
00FE144A  pop         esi    
00FE144B  pop         ebx    
00FE144C  add         esp,0C0h    
00FE1452  cmp         ebp,esp    
00FE1454  call        00FE113B    
00FE1459  mov         esp,ebp    
00FE145B  pop         ebp    
00FE145C  ret//因為_cdecl,所以由呼叫者平衡棧  直接ret即可  



記憶體棧顯示:

地址 說明
003EFC0C     003EFDCC       push edi(edi = 003EFDCC)
003EFC10  00000000 push esi(esi = 00000000)
003EFC14 7EFDE000 push ebx(ebx = 7EFDE000)
003EFC18 cccccccc ESP = ESP - 0X0D8H(216)
003EFC1C cccccccc
003EFC20 cccccccc
................
................
003EFCD4 cccccccc
003EFCD8 cccccccc
003EFCDC 00000003 mov [ebp-14h],3
003EFCE0 cccccccc
003EFCE4 cccccccc
003EFCE8 00000067 mov [ebp-8],eax//103
003EFCEC cccccccc
003EFCF0 003EFDCC EBP = ESP = 003EFCF0
003EFCF4 00FE1447 CALL Function下一條指令地址 EIP儲存
003EFCF8 00000064 push    64h
003EFCFC 00000000 push    0
................
................
................
003EFDCC 003EFE1C EBP--main()
003EFDD0 00FE1989 呼叫main函式返回後的下一條指令地址0x00fe1989

圖形顯示: