对call、retn的深入分析和认识

为了加深对call、retn的理解,我今天用delphi写了一个小程序,在OD中跟踪程序执行call及retn时堆栈的变化。

程序很简单:

对应的汇编代码:

004A4D28   .  B8 3C4D4A00   mov     eax, 004A4D3C                    ;  ASCII "bbbbbbbb"
004A4D2D   .  E8 9EFFFFFF   call    004A4CD0
004A4D32   .  C3            retn

 

004A4CD0  /$  55            push    ebp

...........

004A4D21   .  59            pop     ecx
004A4D22   .  59            pop     ecx
004A4D23   .  5D            pop     ebp
004A4D24   .  C3            retn

执行到004A4D2D,esp=0013F630,F7进去后到达004A4CD0  也就是summ的第一句代码,esp=0013F62C,也就是说执行call xx系统进行了一个压栈操作!执行到 004A4D24时,esp=0013F62C(和执行到第一句代码时相等),执行了retn后,esp=0013F630,也就是说retn进行了一个出栈的动作! 

另外,函数执行完毕的前后,不管是stdcall还是fastcall,都不保证寄存器不被修改!

总结:

1、执行到函数内的第一个语句时的esp值和到最后一个语句(也就是retn)的esp值是一样的:

004A4CD0  /$  55            push    ebp  ;esp=0013F628
004A4CD1  |.  8BEC          mov     ebp, esp
004A4CD3  |.  5D            pop     ebp
004A4CD4  /.  C2 0400       retn    4 ;esp=0013F628 

2、retn 4表示pop 2次。

3、执行到call xx时的esp值与执行完xx时的esp值不一定相等,对stdcall的尤其是这样。 

粗浅分析,不当之处还请指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值