浅谈函数的调用过程,栈帧的创建和销毁

原码:

浅谈函数的调用过程,栈帧的创建和销毁浅谈函数的调用过程,栈帧的创建和销毁


按到 f10 ,转到反汇编:

浅谈函数的调用过程,栈帧的创建和销毁

浅谈函数的调用过程,栈帧的创建和销毁


call命令的功能:1.将当前正在执行指令的下一条指令的地址压入栈中 ;

           2.随即跳转(jmp)至指定函数

ret 返回要做的两件事 :   1.弹出pop栈顶; 

                  2.弹出栈顶的值的地址,并将其写入EIP 。


通过调试,查看调用栈堆窗口,我们可以看到main函数是被 _tmainCRTStartup 函数其他调用的,也生成了栈帧,同时函数的调用过程中,形参的实例化,会形成临时变量。而_tmainCRTStartup函数是在mainCRTStartup被调用的。

栈帧的维护涉及ebp和esp两个寄存器。在函数调用过程中,这两个寄存器存放了维护这个栈的栈底和栈顶指针。

例如,调用main函数时,栈帧维护如下:

浅谈函数的调用过程,栈帧的创建和销毁

浅谈函数的调用过程,栈帧的创建和销毁


ebp存放了指向函数栈帧栈底的地址。

esp存放了指向函数栈帧栈顶的地址。


要详细研究函数调用过程,必须对应汇编代码。

使用add函数来分析函数栈帧的创建和销毁。add函数的汇编代码如下:

浅谈函数的调用过程,栈帧的创建和销毁浅谈函数的调用过程,栈帧的创建和销毁

EIP : CPU中的寄存器,又称PC指针。该寄存器里存储着当前CPU正在处理的指令的下一条指令。



结论:

1.形参实例化在调用函数与被调函数两个栈帧之间;

2.函数的临时变量在自己的栈帧里,生命周期随栈帧,因此具有临时性。

3.每个函数都通过CBP , ESP来形成自己的栈帧。

4.常规情况下,函数的返回值以寄存器形式输出。