C++:提高篇: 栈-寄存器和函数状态:栈指针&&帧指针详解

前言

🚗🚗🚗:在刚接触 ESP和EBP概念时,我一直认为:ESP指向栈顶指针,EBP指向栈底指针,其实这么理解,只对了一半,如果这个栈只有一个 栈帧,那么上述理解就是正确的,如果这个栈再复杂点,存在多个栈帧,那么这个理解就存在问题了。
🛺🛺🛺:EBP不是指向栈底指针,而是指向 栈帧的底部,同样 ESP不是指
向栈的栈顶指针,而是指向 栈帧的顶部。
🚌🚌🚌:

  1. ESP:栈指针寄存器(extended stack pointer):内存存放着一个指针,这个指针永远指向系统栈最上面一个栈帧的栈顶。
  2. EBP:基址指针寄存器(extended base pointer):其内存存放着一个指针,这个指针永远指向系统栈上面一个栈栈的底部。

1、EBP和ESP详解

🛫🛫 1. %ebp叫帧指针,既然叫帧指针,那就是说它是用来存放各帧首地址的指针。
🛬🛬 2. 一个存储单元空间,有两个属性。

1:CPU访问这个存储单元需要依赖的地址值。
2:这个存储单元所存储的数值。

🚀🚀 3. 函数的帧,每个帧首作为存储单元空间,有标识自己的空间地址,同时这个空间地址也存储一个数值。

🚀🚀4. 栈帧灵活运用这个概念,让%ebp始终保存 当前帧首地址。在执行调用者函数caller 时,%ebp 保存这个帧首地址, 而当调用子函数时,子函数callee更细为当前帧,%ebp保存 子函数帧首地址(为了让子函数在返回时,更新%ebp, 使帧指针能顺利回到调用者caller的帧来),所以有必要在 %ebp指向 callee帧首的同时,更改帧首空间内所保存的值为 caller帧首地址, 这个就是概念:“被保存的%ebp” 或者“旧的%ebp值”,父函数(caller)调用时%ebp的值

🚀🚀5. 而%esp 保存 返回地址(这个返回地址就是子函数返回后,父函数需要执行下一条指令的地址)

2、push ,leave ,call汇编指令分析

在下面一段源代码中:

using namespace std;
int son_add(int a,int b) {
    return a+b;  
}

int father(){
    int a = 1;
    int b = 2;
    int sum = 0;
    sum = son_add(a,b);
    return sum;
}

int main(){
    father();
    return 0;
}

在这里插入图片描述
上述代码我从汇编指令角度做三方面分析:分别是 call , push ,leave

  1. call指令:call 指令可以看成近似如下操作,先 :push 返回地址(caller函数),%esp 、然后:jmp 子函数地址。当两个参数入栈完成后,接着就是 father函数的 返回地址(这个地址在子函数返回后,father函数下一条指令就是这个地址),至此函数调用的准备工作完成,可以通过指令jmp 调整到 add_son函数
  2. push %ebp: 在这条语句之前,它保存的是 father的帧首地址,当这条语句执行进行压栈时,push &ebp会使得该帧首地址被顺利放进 “返回地址”单元下面。并且此时:栈帧转移到 add_son的栈帧势力范围内,且又是栈顶,那么%esp就可以存储这个帧首地址***(旧的%ebp地址)***
  3. mov %esp,%ebp:将步骤2 %esp保存的栈顶地址赋值给 %ebp,所以son_add 函数返回前,%ebp作为当前的帧首就不会改变了。
  4. pop %rbp:这个指令实际会做下面两个指令

pop %rbp 等价于下面两个指令
1:move %ebp, %esp
2: pop %ebp
👏👏👏其中指令1完成这个功能 :
修改 %esp的值,让它指向 %ebp 而%ebp就是add_son的帧首地址,这样就完成了这个过程:%esp指向 father的返回地址。
👏👏👏👏 指令2完成这个功能
弹出%ebp即读取它存的数值,而它存的数值就是father的帧首地址。
经过这两个指令就破坏了 son_add 栈帧结构,并且回到了 father栈帧结构。

3、下面用一个图总结

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值