ESP、EIP、EBP寄存器在函数调用时的理解

一、前提知识

1、寄存器空间和内存空间是两个不同存储部分,程序指令和栈一般认定在内存中,而寄存器可以存储数值和某些内存空间地址。

2、栈空间是由高地址向低地址增长的,栈顶就是地址最低的。

3、ESP寄存器往往存储栈顶地址,是动态变化的,PUSH、POP、CALL、RETN汇编指令都会造成ESP存储的值发生变化,ESP始终指向栈顶元素,而不是栈顶下一个元素。

4、EIP寄存器是存放CPU要读取的指令地址,相当于PC计数器。

5、EBP表示一个栈空间的基地址,不同函数的基地址不一样,比如main函数和main函数里调用的函数的EBP值不一样,可能差很多。

二、函数调用过程寄存器变化

假如在main函数中调用一个fun函数,fun包含输入实参para和局部变量var,那么栈空间的变化过程如下:

地址1para
地址2EIP值
地址3EBP值(main的)
地址4var1
地址5var2

1、输入参数会通过PUSH压栈,供fun使用,ESP值变小,EBP值是main的栈基地址。

2、CALL调用fun,此时会将EIP的值入栈,即保存从函数返回之后要执行的指令,因为EIP在fun内可能被修改。

3、fun函数中首先会PUSH EBP的值,即保存main函数的栈基地址,然后把ESP的值赋值给EBP,此时ESP的值和EBP的值相同。

4、然后SUB ESP的值,为局部变量var开辟栈空间,此时ESP始终保持栈顶,EBP保存地址3的值(不是地址3里的EBP值),会通过EBP和偏移地址来操作局部变量(其实只用ESP也能操作,只是这样会不停改变ESP值,会增加指令数目,所以多了EBP事实上是对程序的优化)。

5、fun完成后,首先会把EBP的值赋给ESP(和3相反,此时ESP是地址3),然后POP main的EBP值给EBP寄存器(此时ESP是地址2),EBP寄存器恢复调用前。

6、RETN会POP EIP值至EIP寄存器(此时ESP是地址1),EIP寄存器恢复调用前。

7、然后会对para值进行清理,使得ESP寄存器恢复调用前。

三、总结

1、一个函数调用过程充满了对栈的操作,而这三个寄存器是栈操作相关的,核心思想就是保存原来状态,使用后再恢复。

2、关于7中对参数的回收具体操作,可能在fun内完成,也可能由调用者main完成,具体跟函数的调用方式有关,在C语言中是可以控制的,具体可参考文档:https://www.cnblogs.com/yenyuloong/p/9626658.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值