zoukankan      html  css  js  c++  java
  • 函数调用时函数栈状态分析

    先贴出自己写的测试代码:

    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
    

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

    image

    调用函数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()
    

    image

    调用函数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							// 返回
    

    image

    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 
    

    image

  • 相关阅读:
    SQL基础篇——如何搭建一个数据库
    SQL基础篇---基本概念解析
    联合体与结构体的区别
    结构体和它在链表中的使用
    火线零线地线
    第十二章 泛型
    Winform 控件使用集锦
    全局钩子和局部钩子
    第八章 方法
    第七章 常量和字段
  • 原文地址:https://www.cnblogs.com/quark/p/2407487.html
Copyright © 2011-2022 走看看