vc++6.0中查看函数栈的结构

栈:一种后进先出的数据结构   比如:弹夹

函数调用的约定

     传参顺序

     传参媒介

     如何传递返回值

     平衡参数(堆栈平衡):有且只有被调方(callee)和调用方(caller)一方执行

 

_cdell c约定,在C语言中 默认) <所有号称兼容C标准的编译器>

  从右往左传参,通过栈传递参数,通过寄存器传递返回值,由被调方清除参数空间(平衡参数/堆栈/栈顶)

 

 _stdcall  (标准调用约定)

  从右往左传参,通过栈传递参数,通过寄存器传递返回值,由调用方清除参数空间(平衡参数/堆栈/栈顶)

 

_fastcall <微软,非标准>

  通过寄存器传递前两个参数,其余参数从右往左通过寄存器传递,通过寄存器传递返回值,由被调方清除参数空间

 

函数调用的步骤

1、按被调用约定传递参数

2、保存返回地址

3、流程转移到被调函数的首地址(第一条指令的地址)

4、保存调用方的栈信息(栈底)

5、更新当前栈信息(栈底),换句话说就是指定被调方的栈底位置

6、以局部变量总大小为依据,抬高栈底,也就是说为被调方的局部变量开辟空间

*6.1 在调试选项(/Od + /Zi)时,将局部变量初始化为0xcccccccc

7、保存寄存器环境

8、执行函数体

9、恢复寄存器环境

10、释放局部变量空间

11、恢复调用方的栈信息(栈底)

12A_cdell约定时,直接取出返回地址,并按此地址回到被调方

12B_stdcall _fastcall约定时,取出返回地址后,平衡参数多占用空间,按返回地址回到调用方

*13_cdel约定时,调用方在此时平衡参数所占用空间

其中 * 代表可选项

现在我们到具体函数中分析

#include<stdio.h>
#include<stdlib.h>

int Sum(int a, int b)
{
    int sum = 0;
    //system("pause");
    sum = a + b;

    return sum;
}

int main()
{ 
    int nNum1 = 3;
    
    int nNum2 = 5;

    Sum(nNum1, nNum2);

    system("pause");
    return 0;
}

 

在Ide环境中打开内存窗口,win7 32位 vc++6.0可以直接定位18ff40

接下来我们来具体分析了解如图所示

首先看看main函数的栈结构

接下来我们再看看sum函数的栈结构

 

posted on 2017-12-07 22:29  秋雨丶梧桐  阅读(662)  评论(0编辑  收藏  举报

导航