当前位置:网站首页>函数栈帧的创建和销毁
函数栈帧的创建和销毁
2022-07-03 15:16:00 【小蜗牛向冲】
前言
对于编程这件事来说,函数的调用在代码中是必不可少的,那函数在内存中到底是如何创建和销毁的,下面我将写一个简单的函数为大家演示。
为了更加清楚的理解函数栈帧的创建和销毁,将使用VS2013为大家演示(不同版本的vs演示的效果可能不同),
一 认识寄存器
根据百度百科介绍,寄存器是中央处理器内的组成部分。 寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。 简单来说, 寄存器就是存放东西的 。 从名字来看,跟火车站寄存行李的地方好像是有相似。
在本次函数栈帧的创建和销毁要到寄存器有:
eax
ebx
ecx
edx
esp:栈顶指针
ebp:栈底指针
对于这四个寄存器知道有这些寄存器即可,对于esp和ebp是用来维护函数的。
二 Add函数栈帧的创建和销毁
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Add(int x, int y)
{
int c = 0;
c = x + y;
return c;
}
int main()
{
int a = 10;
int b = 20;
int ret = Add(a, b);
printf("ret = %d\n", ret);
return 0;
}
在调试之前,我们要想一个问题,main函数是程序的入口,但mian函数也是一个函数,那么它又是被什么函数调用的呢?
我们可以调用堆栈进行观察:
这时我们发现main函数是被__tmainCRTStartup函数调用,而__tmainCRTStartup函数又是被mainCRTStartup函数调用。
main函数的调用
int main()
{
00881410 push ebp
00881411 mov ebp,esp
00881413 sub esp,0E4h
00881419 push ebx
0088141A push esi
0088141B push edi
0088141C lea edi,[ebp+FFFFFF1Ch]
00881422 mov ecx,39h
00881427 mov eax,0CCCCCCCCh
0088142C rep stos dword ptr es:[edi]
int a = 10;
0088142E mov dword ptr [ebp-8],0Ah
int b = 20;
00881435 mov dword ptr [ebp-14h],14h
int ret = Add(a, b);
0088143C mov eax,dword ptr [ebp-14h]
0088143F push eax
00881440 mov ecx,dword ptr [ebp-8]
00881443 push ecx
00881444 call 008810E1
00881449 add esp,8
0088144C mov dword ptr [ebp-20h],eax
printf("ret = %d\n", ret);
0088144F mov esi,esp
00881451 mov eax,dword ptr [ebp-20h]
00881454 push eax
printf("ret = %d\n", ret);
00881455 push 885858h
0088145A call dword ptr ds:[00889114h]
00881460 add esp,8
00881463 cmp esi,esp
00881465 call 0088113B
return 0;
0088146A xor eax,eax
}
0088146C pop edi
0088146D pop esi
0088146E pop ebx
0088146F add esp,0E4h
00881475 cmp ebp,esp
00881477 call 0088113B
0088147C mov esp,ebp
0088147E pop ebp
0088147F ret
这些都是调用main函数的准备工作
其中的push ebp指的是压栈,就是把ebp中的指向的值给ebp。
mov ebp,esp.这里是指把esp中的值给ebp
sub esp,0E4h 是指把esp中的值减去0E4h。
push ebx
push esi
push edi压栈三个值
lea edi,[ebp-0E4h]
mov ecx,39h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]这些反汇编就是将mian函数的值,从edi开始下面初始化39次,都初始化为CCCCCCCC
所以,为什么有时候会打印出 烫烫烫烫烫烫,因为变量在初始化时内存里面放的CCCCCC的值。
int a = 10;
mov dword ptr [ebp-8],0Ah这里代码的意思是将a的值放到ptr地址处
mov dword ptr [ebp-8],0Ah
int b = 20;同理是将b的值放到[ebp-8]的地址处
下面就进行函数的传参,那函数传参又是在内存中进行的呢?
mov eax,dword ptr [ebp-14h]
这里就是将[ebp-14h](b的值)中的值放到eax中
push eax
将eax进行压栈
mov ecx,dword ptr [ebp-8]
这里就是将[ebp-14h](a的值)中的值放到ecx中
push ecx
将ecx进行压栈
下面就进行函数调用
00881444 call 008810E1
为了调用的函数参数能够返回,call指令下一条指令的地址。
下面进入到Add函数中的反汇编。
下面这些又是在干什么呢?其实是在维护Add函数的栈帧。
同main函数的维护一样,都是要函数栈帧的准备工作,分配内存,初始化内存。CCCCCCCCCCCCC
int Add(int x, int y)
{
008813C0 push ebp
008813C1 mov ebp,esp
008813C3 sub esp,0CCh
008813C9 push ebx
008813CA push esi
008813CB push edi
008813CC lea edi,[ebp+FFFFFF34h]
008813D2 mov ecx,33h
008813D7 mov eax,0CCCCCCCCh
008813DC rep stos dword ptr es:[edi]
int c = 0;
008813DE mov dword ptr [ebp-8],0
c = x + y;
008813E5 mov eax,dword ptr [ebp+8]
008813E8 add eax,dword ptr [ebp+0Ch]
008813EB mov dword ptr [ebp-8],eax
return c;
008813EE mov eax,dword ptr [ebp-8]
那函数的值又是怎么返回的呢?形参不是会销毁吗?
mov eax,dword ptr [ebp-8]
这里是将[ebp-8](30)的值保持在eax中。
008813F1 pop edi
008813F2 pop esi
008813F3 pop ebx
008813F4 mov esp,ebp
008813F6 pop ebp
008813F7 ret那这些又是指的是什么?
pop指的是出栈的意思,使得esp不断加加。
其中的mov esp,ebp是将ebp的值给esp,在 pop ebp 这样esp和ebp维护的空间重新指向main函数。ret是回到函数调用,call指令的下一个地址。
这样我们就是完成了main函数的创建和Add函数创建和销毁。而main函数的销毁和Add函数的销毁是类似的。
下面我们来回答几个问题,来运用我们今天学习的。
1 局部变量是如何创建的?
首先为函数分配好空间,在为函数初始化,最后在为局部变量在分配好的空间中,分配好地址。
2 为什么局部变量不初始化内容是随机的?
因为我们在为函数初始化的时,就是初始化的随机值。
3 函数调用时参数时如何传递的?传参的顺序是怎样的?
将参数存入eax寄存器中,传参的顺序是从右到左。
4函数调用的结果是如何返回的?
通过call指令记住下一条指令的地址,从而找到main函数,在通过寄存器将返回值带到,main函数中。
总结
通过对Add函数创建和销毁的理解,我们相信大家对于函数在内存中的分配会有更加深刻的理解。在下面的博客中,博主会给大家带来更多知识,希望大家不要错过噢!
边栏推荐
- Leasing cases of the implementation of the new regulations on the rental of jointly owned houses in Beijing
- Global and Chinese market of Bus HVAC systems 2022-2028: Research Report on technology, participants, trends, market size and share
- 【Transform】【实践】使用Pytorch的torch.nn.MultiheadAttention来实现self-attention
- Explanation of time complexity and space complexity
- Centos7 deployment sentry redis (with architecture diagram, clear and easy to understand)
- App global exception capture
- Functional modules and application scenarios covered by the productization of user portraits
- Puppet automatic operation and maintenance troubleshooting cases
- Characteristics of MySQL InnoDB storage engine -- Analysis of row lock
- Chapter 14 class part 1
猜你喜欢
视觉上位系统设计开发(halcon-winform)-5.相机
[transform] [NLP] first proposed transformer. The 2017 paper "attention is all you need" by Google brain team
redis缓存穿透,缓存击穿,缓存雪崩解决方案
【云原生训练营】模块八 Kubernetes 生命周期管理和服务发现
【云原生训练营】模块七 Kubernetes 控制平面组件:调度器与控制器
什么是embedding(把物体编码为一个低维稠密向量),pytorch中nn.Embedding原理及使用
Can‘t connect to MySQL server on ‘localhost‘
[attention mechanism] [first vit] Detr, end to end object detection with transformers the main components of the network are CNN and transformer
Byte practice plane longitude 2
B2020 points candy
随机推荐
视觉上位系统设计开发(halcon-winform)-1.流程节点设计
Relationship between truncated random distribution and original distribution
Global and Chinese market of solder bars 2022-2028: Research Report on technology, participants, trends, market size and share
Besides lying flat, what else can a 27 year old do in life?
Kubernetes vous emmène du début à la fin
Markdown file titles are all reduced by one level
PyTorch crop images differentiablly
[transform] [NLP] first proposed transformer. The 2017 paper "attention is all you need" by Google brain team
SQL server installation location cannot be changed
Global and Chinese market of transfer case 2022-2028: Research Report on technology, participants, trends, market size and share
官网MapReduce实例代码详细批注
5-1 blocking / non blocking, synchronous / asynchronous
Puppet automatic operation and maintenance troubleshooting cases
Introduction to redis master-slave, sentinel and cluster mode
Using Tengine to solve the session problem of load balancing
Global and Chinese market of postal automation systems 2022-2028: Research Report on technology, participants, trends, market size and share
Tensor ellipsis (three points) slice
Characteristics of MySQL InnoDB storage engine -- Analysis of row lock
406. Reconstruct the queue according to height
Incluxdb2 buckets create database