来一起聊聊栈帧吧!!!

       今天我们一起来探讨探讨栈帧。那么,首先呢,我们先想一下为什么要讨论栈帧呢?我想大家应该听说过不少次函数调用时,变量具有临时性。那么这个所谓的临时性怎么体现出来呢?那么心里揣着这个疑问,由我们接下来慢慢讨论!

     1. 讨论前的准备工作:

                               32位cpu通用寄存器:EAX,EBX,ECX,EDX,EBP,ESP,ESI,EDI(可用于传送和暂存数据)

                                EBP:指向栈帧的底部

                                ESP:指向栈帧的顶部 

                               PC程序计数器:EIP(当前正在执行的下一条指令的地址)

                               栈帧的特点:先进后出(就如同一条只有一辆车宽的车道,第一辆车从车道入口开进去就放在了最里边,                                                      它想出来就 必须等后面的车从车道入口出去之后才能出去)

                               栈帧操作:push:把一个新值压入到栈帧顶部,。(把车从车道入口开进去)

                                                 pop: 把一个栈里的值移出去。(把车从车道入口开出去)

        现在我们有了初步的知识储备,那现在就让我们一起来捋一捋函数调用时的大致过程。那么现在看看下面的函数:

#include<stdio.h>
#include<windows.h>
int Add(int a, int b){
int ret = a + b;
return ret;
}
int main(){
int a = 10;
int b = 20;
int c = Add(a, b);
printf("%d", c);
system("pause");
return 0;
}

        上面是一个简单的调用Add函数的简单的代码

        2.探讨函数调用过程:

                                      (1)想象出一个栈空间;

                                      (2)调出代码的汇编语言,根据汇编语言进行行动;

来一起聊聊栈帧吧!!!

来一起聊聊栈帧吧!!!

        经上述便利之后,我们想象中的栈帧结构图大致为: 来一起聊聊栈帧吧!!!  

此时函数即将开始调用:                    来一起聊聊栈帧吧!!!

此时栈帧空间里已经形成了形参实例化的a和b:      

 来一起聊聊栈帧吧!!!

之后跳转至Add函数:来一起聊聊栈帧吧!!!

此时的Add函数的栈帧就开辟出来,并且对a和b做了一些列的运算操作:

来一起聊聊栈帧吧!!!

现在就是函数返回的过程:

来一起聊聊栈帧吧!!!

此时ebp已经指回main函数的栈底:

来一起聊聊栈帧吧!!!\

然而此时Eip中存放的是下一条指令的地址(002c1449):

来一起聊聊栈帧吧!!!

此时,可以看看esp,ebp,各自的指向(注意这个函数中说的加多少都是加其类型的大小):

来一起聊聊栈帧吧!!!

    3:总结:

                 (1)函数调用时会形成栈帧结构;

                 (2)在函数调用完毕之后数据就失效了(注意不是清零),这也就是临时性的体现;

                 (3)栈帧的结构是自上向下的走向;

          好了,这也是我半桶水的理解,希望你们有好的见解评论给我。

           不说了,打代码去了(别问代码是谁)!!!!!