寄存器
esp:记录栈顶位置,即指向栈顶的指针
ebp:记录栈底位置,即指向栈底的指针
eip:指向程序当前运行位置的指针
栈帧运作过程
我们以main函数调用fun函数为例
1.eip压栈,保存当前main函数执行位置
2.ebp压栈,保存main函数栈帧的栈底
3.准备工作已经做完,开始调用fun函数。
4.将esp的值赋给ebp,作为fun函数的栈底
5.esp值减少0x18,为fun函数开辟0x18大小的栈空间(小端存储中栈逆向生长)
6.fun函数调用完成,开始返回main函数
7.执行leave(mov esp ebp; pop ebp),我们分为两步执行,leave1和leave2
8.执行leave1,将ebp值赋值给esp,释放栈空间
9.pop ebp,此时ebp所指向的内存中的内容即为之前压入的ebp的main函数的栈底(步骤2),即ebp重新指向main函数栈底
10.执行ret(pop eip),弹出栈顶值到eip寄存器,此时的栈顶值为先前压入的main函数的执行位置(步骤3)
此时一次调用完成,栈刚好回到调用前的状态。