esp,ebp分别指向函数栈顶和栈底,维护栈帧,调用函数对栈来说分为:1.创建压入形参 和 原函数记录。 2.调用的函数的开始准备工作 3.创建局部变量和使用形参 4.返回继续执行原函数
一.创建压入形参 和 原函数记录
以main函数调用另一个函数为例,先压入形参..到形参1,再压入调用函数执行完main的下一条地址,再压入此时ebp的值。这样恢复时pop值到ebp,ebp恢复,在POP下一条指令地址到指令寄存器,pop形参销毁,直接进行下一步了。
二.调用的函数的开始准备工作
1.开辟栈帧。
先将esp的值给ebp,再esp减少,维护一段新的空间
2.压入一些寄存器的值edi,esi,ebx等(分别表示初始化空间时值,次数,大小),用于传值初始化ebp到esp的空间
三。创建局部变量和使用形参
1.根据ebp+偏移找到栈中空余位置并初始化空间:
例:int a=0;
2.根据ebp的偏移找到并使用形参1,2....
例:a=x1
四.返回继续执行原函数
1.将要返回的值给寄存器如:eax.
2.pop掉edi,esi,ebx后,ebp的值给esp。pop ebp(ebp-main值给ebp,还原)
3.再pop,将下一条指令地址给指令寄存器,再pop,销毁形参,继续执行
总结:
三步调用函数栈帧改变:记录状态。创建开辟。返回还原。