浅谈函数的调用过程,栈帧的创建和销毁
原码:
按到 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.常规情况下,函数的返回值以寄存器形式输出。