函数调用原理————栈帧
1.栈
栈是向下生长的,也就是由内存高地址-》低地址的。栈有自己的栈顶指针和栈底指针。
ebp : 称为“基址指针”,在未改变之前一直指向栈底
esp : 称为“栈指针” , 随着数据的入栈和出栈移动,也就是说一直指向的是栈顶
2.了解一些简单的汇编指令
call(函数调用) : 先将当前指令的下一条指令地址压栈,然后跳转到被调用的函数处。
ret (函数返回)?: 把call指令压栈的内容出栈,然后执行这块内容所指向的指令
3.函数的调用过程描述
如下图: main函数调用fun函数。(注意,其实在程序运行时,main函数是被start函数所调用的)
①: 查看汇编代码,发现main函数调用fun函数时,用了call命令调用fun函数
②: 先将main函数堆栈的ebp压栈(这个时候,main函数的esp向下移动),保存main函数的任务信息。
③: 把esp的值付给ebp,也就是把ebp指向esp,这个时候就创建了fun函数的栈底
④: 然后在这个栈底上(用sub指令)开辟一块空间作为fun函数的占空间,esp指向fun函数的栈顶
⑤: (通过一些寄存器来实现这块栈空间的初始化,过程我们不讨论)fun函数运行完成后返回,
(通过mov指令)让esp指向ebp,这时fun函数的栈底ebp恢复为main函数的栈顶esp,
然后让ebp出栈,ebp回到main函数的栈底,(通过ret指令)返回main函数,这个时候ebp和esp回到了原来的位置
栈恢复到了fun函数被调用的状态。