函数栈帧的创建与销毁(上)

简介: 笔记

什么是函数栈帧


我们在写C语言代码的时候,经常会把一个独立的功能抽象为函数,所以C程序是以函数为基本单位的。

那函数是如何调用的?函数的返回值又是如何待会的?函数参数是如何传递的?这些问题都和函数栈帧

有关系。

函数栈帧(stack frame)就是函数调用过程中在程序的调用栈(call stack)所开辟的空间,这些空间

是用来存放:

函数参数和函数返回值

临时变量(包括函数的非静态的局部变量以及编译器自动生产的其他临时变量)

保存上下文信息(包括在函数调用前后需要保持不变的寄存器)。


什么是栈?


栈(stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函

数,没有局部变量,也就没有我们如今看到的所有的计算机语言。


与函数栈帧有关的汇编语句


eax:通用寄存器,保留临时数据,常用于返回值

ebx:通用寄存器,保留临时数据

ebp:栈底寄存器

esp:栈顶寄存器

eip:指令寄存器,保存当前指令的下一条指令的地址

mov:数据转移指令

push:数据入栈,同时esp栈顶寄存器也要发生改变

pop:数据弹出至指定位置,同时esp栈顶寄存器也要发生改变

sub:减法命令

add:加法命令

call:函数调用,1. 压入返回地址 2. 转入目标函数

jump:通过修改eip,转入目标函数,进行调用

ret:恢复返回地址,压入eip,类似pop eip命令(返回子程序)

函数如何创建栈帧并销毁

当程序进入main函数时,要给main函数在栈区创建空间,esp(栈顶)和ebp(栈底)对main函数进行维护

4.png


当程序执行时,我们在调试窗口对堆栈段进行调用,我们可以看到main函数是被__tmainSRTStartup函数所调用,说明main函数是它的内部函数,而__tmainSRTStartup又是被mainCRStartup这个函数调用

5.png

梳理一下上面的思路

6.png

这些函数在堆栈当中的存储

7.png

main函数栈帧开辟


接下来重新调试,我们转到反汇编

8.png


调用main函数之前,esp和ebp对调用main函数的函数进行维护 ,当栈顶发生改变时,esp会指向新的栈顶

9.png


003118B0  push        ebp  

003118B1  mov         ebp,esp  

先把ebp入栈,然后把ebp移动到esp的位置


10.png


003118B3  sub         esp,0E4h  

003118B9  push        ebx  

003118BA  push        esi  

003118BB  push        edi  


之后又把esp往上移动,移动完把ebx,esi,edi压栈,esp和ebp现在指的这块空间是为main函数预先开辟好的


11.png12.png13.png


把edi-0EFH也就是main函数开始的这里的地址,放到edi里面去,然后从这个地址开始赋值39次的双字节数据,赋值为CCCC


14.png


到这里main函数栈帧开辟完成


15.png


接下来就是在main函数的空间里,创建三个变量,并给赋值

16.png

相关文章
|
6月前
|
编译器
函数栈帧的创建和销毁
函数栈帧的创建和销毁
32 0
|
7月前
|
存储 编译器 容器
函数栈帧的创建和销毁讲解
函数栈帧的创建和销毁讲解
48 0
|
7月前
|
编译器 容器
关于函数栈帧的创建和销毁
关于函数栈帧的创建和销毁
|
存储
函数栈帧的创建和销毁(下)
函数栈帧的创建和销毁(下)
55 0
|
7月前
|
容器
函数栈帧的创建和销毁介绍
函数栈帧的创建和销毁介绍
44 0
|
7月前
|
存储 编译器
初识函数栈帧的创建与销毁(笔记)
初识函数栈帧的创建与销毁(笔记)
|
编译器 程序员 C语言
函数栈帧的创建与销毁(超详解)
函数栈帧的创建与销毁(超详解)
116 0
|
存储 缓存 编译器
函数栈帧的创建与销毁
函数栈帧的创建与销毁
45 0
|
存储 C语言 C++
你知道函数栈帧的创建和销毁吗?
你知道函数栈帧的创建和销毁吗?
78 0
|
存储 编译器 C++
深入理解内存 —— 函数栈帧的创建与销毁
深入理解内存 —— 函数栈帧的创建与销毁
133 0