您的位置:首页 > 编程语言 > C语言/C++

函数调用时函数栈状态分析

2015-07-31 11:55 1136 查看
先贴出自己写的测试代码:
int* M2(int* p)
{
return p+1;
}

int M(int a, char b)
{
int* pp = M2(&a);
return *pp;
}

int _tmain(int argc, _TCHAR* argv[])
{
int e=0;
int d = M(3,'c');

getchar();
return 0;
}


然后来一层一层的分析:

调用函数Main

008B1030  push        ebp       // 将ebp的值压入栈
008B1031  mov         ebp,esp               // 将esp的值赋值给ebp
008B1033  sub         esp,8             // esp-8,为了空出变量e,d的空间
int e=0;
008B1036  mov         dword ptr [e],0           // 将e的值设置为0
int d = M(3,'c');
008B103D  push        63h               // 将'c'压入栈
008B103F  push        3                 // 将整数3压入栈
008B1041  call        M (8B1010h)           // 调用函数M


此时函数堆栈的情况大致如下:



调用函数M

int M(int a, char b)
{
01391010  push        ebp				// 将ebp的值压入栈
01391011  mov         ebp,esp				// 将esp的值赋值给ebp
01391013  push        ecx				// ecx压入栈
int* pp = M2(&a);
01391014  lea         eax,[a]				// 将变量a的地址赋给eax
01391017  push        eax				// 将eax压入栈
01391018  call        M2 (1391000h)			// 调用函数M2()


此时函数堆栈的情况大致如下:



调用函数M2

int* M2(int* p)
{
01391000  push        ebp					// ebp入栈
01391001  mov         ebp,esp					// ebp = esp
return p+1;
01391003  mov         eax,dword ptr [p]				// eax = p;
01391006  add         eax,4					// eax+=4;
}
01391009  pop         ebp					// 将栈顶的值弹出给ebp
0139100A  ret							// 返回



01391018  call        M2 (1391000h)		// 调用函数M2()

0139101D  add         esp,4			// esp+=4
01391020  mov         dword ptr [pp],eax	// eax的值赋给pp
return *pp;
01391023  mov         ecx,dword ptr [pp]	// 将pp指向的地址赋值给ecx
01391026  mov         eax,dword ptr [ecx]	// 将ecs指向的地址赋值为eax
}
01391028  mov         esp,ebp
0139102A  pop         ebp
0139102B  ret

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  汇编 C/C++ 函数调用