C语言的栈帧

简介: C语言的栈帧

有如下函数,其中有函数的并行调用和嵌套调用:

include

int g = 1;
double a(double x,double p){ p = x;
return x;
}
int d(int x){
return x;
}
int c(int x,int p){ p = x;
return d(3)+x;
}
int b(int x){
int a,b;
b = c(4,&a);
printf("%d\n",a);
return b+x;
}//代码效果参考:http://www.zidongmutanji.com/bxxx/393430.html

typedef struct Point_t{
double x,y;
}Point;

Point e(Point a){
return a;
}

main()
{
Point pt;
pt.x = 1.25;
pt.y = 2.75;
int s = a(1.25,&(pt.x));
s += b(5);
s+= g;
printf("%d %lf\n",s,pt.x);
e(pt);
getchar();
}
1 全局变量已在程序执行前加载(加载阶段)

2 系统调用main函数

main函数调用前EBP与ESP的初始值:

3 EBP压栈并更新,抬高esp

0x12FF48-0x78 = 12FED0

4 保存寄存器状态

(寄存器值压栈,栈顶操作,78h以外)

push时,esp抬高(址值减小);

5 栈帧(这里安排了78h个字节)的初始化(调试模式下)

6 main函数的数据在此栈帧上操作

ebp-x,也就是从栈底操作。

7 调用函数前参数压栈

(栈顶操作,78h以外)

注意传址时,压的地址还是ebp-x。也就是主调函数的局部变量地址。

8 main()调用a()

对参数的引用:ebp+x

返回double的汇编指令:

fld qword ptr [ebp+8]

函数返回,通过以下几个汇编指令,esp、ebp回退:

00401079 pop edi
0040107A pop esi
0040107B pop ebx
0040107C mov esp,ebp
0040107E pop ebp
0040107F ret
通过以下汇编,esp降到压参前的位置:

004011E4 add esp,0Ch

函数返回值类型转换,值返回:

004011E7 call __ftol (0040176c)

004011EC mov dword ptr [ebp-14h],eax

9 main()调用b()

main()调用完a(),再调用b(),a()与b()之间是并行调用关系(都由main调用),并行调用关系的函数的栈帧是相互叠加关系,后面调用的函数覆盖在前面函数的栈帧上。

10 b()调用c()

11 c()调用d()

函数嵌套调用时,栈帧上下叠加。

12 函数d()、c()、b()返回

函数d()返回后,剩下main()、b()、c()的栈帧;

函数c()返回后,剩下main()、b()的栈帧;

函数b()返回后,剩下main()的栈帧;

13 main()函数调用e()

13.1 ebp、esp初始值

esp: 0012FEC4
……
ebp: 0012FF42
图示:

pt两个分量对应的16进制值:

1.25 3F F4 00 00 00 00 00 00

2.75 40 06 00 00 00 00 00 00

13.2 压参

13.3 当返回值不是整型或浮点型时

当被调函数的返回值不是整形或浮点型的复合类型时,用寄存器保存不了,需要将返回值保存到主调函数的栈帧空间。

对应以下内存映像:

13.4 返回值保存到被调函数栈空间并赋值函数保存返回值的临时空间

14 总结

函数并行被调用:栈帧相互叠加(重叠);

函数嵌套调用:栈帧上下叠加(不重叠);

函数的递归调用也是一种嵌套调用,所以栈内存的增长会很快!

函数调用时建立栈帧,但栈帧并不只限于栈的push、pop操作esp,且也可以通过ebp进行偏移,也可以将主调函数的栈帧上的局部变量的地址通过通过参数压到栈上,被调函数通过间接寻址来访问主调函数的局部变量空间(如传址和值返回一个复合类型的值)。

相关文章
|
1月前
|
C语言
链栈的初始化以及用C语言表示进栈、出栈和判断栈空
链栈的初始化以及用C语言表示进栈、出栈和判断栈空
21 3
|
1月前
|
C语言
数据结构之栈详解(C语言手撕)
数据结构之栈详解(C语言手撕)
50 1
|
1月前
|
机器学习/深度学习 存储 算法
C语言栈与递归的实现讲解
C语言栈与递归的实现讲解
39 0
|
1月前
|
C语言
C语言栈的行编辑程序讲解
C语言栈的行编辑程序讲解
58 0
|
1月前
|
C语言
C语言栈的括号匹配的检验讲解及相关代码
C语言栈的括号匹配的检验讲解及相关代码
55 0
|
1月前
|
存储 安全 C语言
C语言抽象数据类型栈的定义讲解
C语言抽象数据类型栈的定义讲解
29 0
|
1月前
|
存储 C语言
C语言栈的表示和实现的定义讲解
C语言栈的表示和实现的定义讲解
34 0
|
14天前
|
C语言 C++
【数据结构】C语言实现:栈(Stack)与队列(Queue)
【数据结构】C语言实现:栈(Stack)与队列(Queue)
|
22天前
数据结构——栈(C语言版)
数据结构——栈(C语言版)
11 0
|
1月前
|
机器学习/深度学习 算法 编译器
【C语言】函数 ---- 函数的嵌套调用和链式访问、函数的声明和定义、变量的声明和定义、函数递归与迭代、递归时的栈溢出问题
【C语言】函数 ---- 函数的嵌套调用和链式访问、函数的声明和定义、变量的声明和定义、函数递归与迭代、递归时的栈溢出问题
56 0