Assembly call和ret指令

很多人不知道call和ret的具体动作,只知道call的时候会跳转到被调用函数的地址继续执行指令,ret会直接跳转到返回地址,至于寄存器和栈上的变化不是很了解。

0x00 定义

  • CALL pushes the return address onto the stack and transfers control to a procedure.
  • RET pops the return address off the stack and returns control to that location.

0x01 解释

call指令隐含操作push EIP,ret指令隐含操作 pop EIP,两条指令完全对应起来.

EIP寄存器用于保存下一个要执行的命令地址。在函数返回的过程最后执行ret,就是把之前入栈的返回地址出栈,并放入到EIP寄存器。这样指令就不会顺序继续执行了,而是跳了一下,跳到EIP指向的地方。

相应的,调用call指令的时候,会把下一个要执行的命令地址入栈。

0x02 汇编代码

函数调用

 30: print_out(0, 2);
013D155E push 2 //第二个实参压栈
013D1560 push 0 //第一个实参压栈
013D1562 call print_out (13D10FAh)//返回地址压栈,本例中是013D1567,然后调用print_out函数
013D1567 add esp,8  //两个实参出栈
//注意在call命令中,隐含操作是把下一条指令的地址压栈,也就是所谓的返回地址

函数返回

013D1431 mov esp,ebp //ebp的值传给esp,也就是恢复调用前esp的值
013D1433 pop ebp //弹出ebp,恢复ebp的值
013D1434 ret  //把返回地址写入EIP中,相当于pop EIP

0x03 堆栈变化

函数调用
函数调用过程

函数调用的过程是EBP和ESP分别向栈顶移动的过程,注意EBP是实参和返回地址入栈以后相对于ESP先入栈的。

函数返回
函数返回过程

明显能看到在ret的时候,esp自动减了一个栈指针的大小(不知道这样描述是否准确,不是一个栈帧的大小,因为函数执行的指令集合是一个栈帧),返回地址出栈,进入EIP寄存器(这里没有画出来)。

这里写图片描述

0x04 参考文献

函数调用–函数栈

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值