函数栈帧详解

目录

一.什么是函数栈帧

1.寄存器:

2.函数栈帧

3.栈帧的作用和维护

4.栈帧结构

二.函数栈帧的创建

1.汇编代码

 2.main函数函数栈帧的创建

1.汇编语言讲解:

 2.栈帧创建:

 3.详细步骤

3.ADD函数栈帧的创建

栈帧创建:

3.函数栈帧的销毁

1.汇编语言讲解

 2.详细步骤

4.收获和问题

1.函数如何传参

2.函数返回值如何返回

3.函数中变量如何初始化和赋值

4.函数如何调用如何返回

5.函数执行结束后系统进行了什么操作


一.什么是函数栈帧

1.寄存器:

函数栈帧的创建和销毁离不开寄存器,了解函数栈帧之前先了解一下cpu中的寄存器。cpu中供应用程序员使用的寄存器主要有通用寄存器(EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI),段寄存器(CS、DS、SS、ES、FS、GS),标志和控制寄存器(EIP、EFLAGS)。其中EBP一般用作基址指针,ESP一般用作堆栈指针。

2.函数栈帧

函数被调用时,系统会在栈区为该函数开辟一块栈空间,这个栈空间就是该函数的函数栈帧。以main函数的调用为例,main函数是被__tmainCRTStartup函数调用的,__tmainCRTStartup函数又是被mainCRTStartup函数调用的。当main函数被调用时就会在栈区为其开辟一块空间来用于main函数的执行。

3.栈帧的作用和维护

栈帧也叫过程活动记录,是编译器用来实现函数调用过程的一种数据结构。从逻辑上讲,栈帧为一个函数提供了执行环境。栈是先用高地址再用低地址,栈帧控制和保存了一个函数所需要的各种信息。栈帧的维护离不开ebp和esp寄存器,ebp存放了指向栈帧的栈底地址的指针,esp则存放指向栈顶地址的指针

4.栈帧结构

栈帧就是栈区的一块空间而已,用main函数的栈帧示意图来说明一下吧。

函数栈帧详解_第1张图片

有栈顶指针,栈底指针,栈区大小E4h个字节,栈帧内存放main函数的各种数据。

二.函数栈帧的创建

以一段代码为例(环境为VS2019)

#include 
int ADD(int x, int y) {
	int z = 0;
	z = x + y;
	return z;
}
int main() {
	int a = 10;
	int b = 20;
	int c = 0;
	c = ADD(a, b);
	printf("%d", c);
	return 0;
}

1.汇编代码

 要研究函数栈帧我们要研究c程序的汇编代码。如图所示:

函数栈帧详解_第2张图片

函数栈帧详解_第3张图片

 2.main函数函数栈帧的创建

1.汇编语言讲解:

函数栈帧详解_第4张图片

函数栈帧详解_第5张图片

 2.栈帧创建:

函数栈帧详解_第6张图片

 3.详细步骤

函数栈帧详解_第7张图片

函数栈帧详解_第8张图片

函数栈帧详解_第9张图片

 函数栈帧详解_第10张图片

 函数栈帧详解_第11张图片

 至此main函数的函数栈帧的创建和数据初始化就完成了。

3.ADD函数栈帧的创建

函数栈帧详解_第12张图片

add函数栈帧的创建和main函数栈帧创建是一样的,需要注意的是,ADD函数执行结束后的返回值保存在了寄存器eax中,就是避免ADD函数栈帧销毁时,主函数无法访问ADD返回值。由此可见函数返回值是如何返回的。 

栈帧创建:

函数栈帧详解_第13张图片

3.函数栈帧的销毁

以ADD函数函数栈帧的销毁为例

1.汇编语言讲解

函数栈帧详解_第14张图片

 2.详细步骤

函数栈帧详解_第15张图片

main函数函数栈帧的创建和销毁和ADD函数一样,就不再重复说了。

4.收获和问题

1.函数如何传参

以这一段代码为例

函数栈帧详解_第16张图片

 

2.函数返回值如何返回

函数栈帧详解_第17张图片

3.函数中变量如何初始化和赋值

函数栈帧详解_第18张图片

4.函数如何调用如何返回

函数栈帧详解_第19张图片

5.函数执行结束后系统进行了什么操作

函数栈帧详解_第20张图片

你可能感兴趣的:(c语言,栈,堆栈)