函数调用过程的栈帧

 

用一段简单的代码来看一下main函数是怎样调用的别的函数的

#include <stdio.h>

int myfunction(int x,int y)
{
int z = x+y;
return z;
}
int main()
{
int a = 0xaaaaaaaa;
int b = 0xbbbbbbbb;
int c = myfunction(a,b);
printf("将会运行到这里 ret = %d",c);
return 0;
}

反汇编之后





其中有三个最重要的寄存器要介绍一下,EBP、ESP、EIP。

其中EBP是基址寄存器,用来存放指针,指向栈底。

ESP是栈指针寄存器,用来存放指针,指向栈顶。

EIP也叫IP或PC是程序计数器,用来保存当前正在执行指令的下一条指令的地址。

还有两个较复杂的命令,call和ret.

call命令的作用1.调用函数时通过修改EIP实现函数的跳转()2.将下一条指令的地址保存在EIP,返回值压入栈中

开始时,EBP指向栈底,EIP栈顶。

当运行到箭头的位置时

mov是将b移动到了EAX寄存器中,并压栈(先进去的后出,换言之压数据和出数据都是从栈顶)

如图

同理a也是

执行call指令时先把下一条指令的地址保存起来并压入栈中。


再通过修改EIP实现函数跳转(JMP)



PUSH ebp是将ebp中内容即main函数的代码压入栈顶。


mov ebp,esp之后原来的ebp也指向了esp的位置


sub命令让esp下移了一段为myfunction函数开辟了一段空间


其余的就是对内容进行初始化,直接走到int z = x+y

mov eax,dword ptr [x]将x的内容aaaaaaaa放到eax中

add将x和y加起来放入eax中

mov将eax 的值放到z中,z的地址是ebp-8


mov dword ptr[z]将z放入eax中

与之前push相对的pop

mov esp,ebp将ebp的内容放到esp中,此时esp的内容也变成了ebp

pop ebp是把ebp指向内存单元的内容即main:code放入寄存器中并使ebp指向008ff9a8



ret 函数调用完成返回原来的位置,eip中将会保存原来的地址00be1429

出栈后栈顶回退


add esp,8即esp+8


mov eax中的内容到c中


到此main函数调用myfunction函数就结束了。






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值