EBP ESP 与 CAL

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

posted on 2014-10-18 08:53  大呵呵  阅读(229)  评论(0编辑  收藏  举报

导航