EBP 栈底指针(会随进入不同的函数而改变, 更喜欢手动改变, 自动的有时会画蛇添足)
ESP栈顶指针(永远指向栈顶)
CAL调用函数(隐含操作是将EIP的值入栈, 并将EIP设置为CALL指向的地址)
示例:
main()函数中的EBP = ESP = 12FF7C
void fun2(int a, int b)
{
int x = a;
int y = b;
}
调用fun2()时, 首先入栈的数据是:fun2()的两个形参a,b(cdecl先将b入栈), ESP+8
再将fun2()返回后的,EIP的值0040104B入栈 ESP+4
再将EBP入栈,保存main()中EBP的值以便fun2()返回后正确使用栈. ESP+4
再MOV EBP, ESP 设置fun2()内部的EBP EBP=ESP
再SUB ESP, 8 给fun2()函数内的两个临时变量分配栈空间 ESP-8
再MOV ESP, EBP 将ESP复位 ESP=EBP(考虑是否可以ADD ESP, 8)
再POP EBP 恢复EBP原值, 即12FF7C ESP+4
最后, RETN也触发一次POP操作,即ESP的值增加了, 恢复到0012FF7C. ESP+4
返回到main()后, 还需要ADD ESP, 8 这点需要留意, 以便恢复调用fun2()前, ESP的值
进入fun2()函数后,反汇编如下:
PUSH EBP
MOV EBP, ESP
SUB ESP, 8
MOV DWORD PTR SS:[EBP-4], 3
MOV DWORD PTR SS:[EBP-8], 4
MOV ESP, EBP
POP EBP
RETN