欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Assembly call和ret指令

程序员文章站 2022-04-12 23:32:08
...

很多人不知道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 堆栈变化

函数调用
Assembly call和ret指令

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

函数返回
Assembly call和ret指令

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

Assembly call和ret指令

0x04 参考文献

函数调用–函数栈

相关标签: 汇编