当前位置: 首页 > article >正文

函数栈帧的小知识理解

栈帧这是一块基础而又容易被忽略的知识

1.寄存器(独立的,集成到cpu上)

ebp esp 存放地址 维护函数栈帧的

每一个函数调用,都要在栈创建一个空间,就是由ebp和esp维护两端的,包括main函数

简单通过一段代码来解释一下过程

#include <stdio.h>

void foo(int a, int b) {
    int c = a + b;
    printf("c = %d\n", c);
}

int main() {
    int x = 5;
    int y = 10;
    foo(x, y);
    return 0;
}

这是一个简单的调用算出两数之和的程序 

首先我们进入main函数的时候,我们从vs的反汇编里去看

main:
    push    rbp
    mov     rbp, rsp
    sub     rsp, 16
    mov     DWORD PTR [rbp-4], 5
    mov     DWORD PTR [rbp-8], 10
    mov     eax, DWORD PTR [rbp-4]
    mov     esi, DWORD PTR [rbp-8]
    mov     edi, eax
    call    foo
    mov     eax, 0
    leave
    ret

首先我们push rbp的时候线保存我们main的指针

mov     rbp, rsp设置当前帧指针

这样,我们的rbp,rsp指针都指向了main函数的栈顶

在接下来的 sub     rsp, 16 这一步就是为我们的main函数开辟了16字节的空间

mov     DWORD PTR [rbp-4], 5 
mov     DWORD PTR [rbp-8], 10 

这两个move就把5和10压栈入我们的局部变量x和y中

  • mov eax, DWORD PTR [rbp-4]
  • mov esi, DWORD PTR [rbp-8]
  • mov edi,eax

这是将我们的变量加载到寄存器中

call foo:调用 foo 函数


接下来的foo函数里面

  • push rbp
  • mov rbp, rsp
  • sub rsp, 16

这里和main函数大同小异,都是保存指针,开辟栈帧空间

然后是把变量存储起来放入寄存器中计算,得出结果并且打印

  • leave
  • ret

恢复调用者的帧指针,返回到调用者,把开辟的栈帧空间销毁

由于开辟地址是由高到低的,所以我们会发现如果下面我们在重复一次调用foo函数,里面变量的地址也是不变的

最后加上一点寄存器的总结

总结

  • eax/rax:用于存储函数的返回值。
  • edi/rdiesi/rsi:在 System V AMD64 ABI 调用约定中,用于传递函数的第一个和第二个参数。
  • rcxrdx:在 Microsoft x64 calling convention 调用约定中,用于传递函数的第一个和第二个参数。

理解好函数栈帧的调用对于我们的理解以及计算空间复杂度都是很有利的,多多尝试理解会有好处


http://www.kler.cn/a/301158.html

相关文章:

  • 机器学习(1):线性回归概念
  • OceanBase数据库设计与管理:构建高效分布式数据架构基石
  • 2025-微服务—SpringCloud-1~3
  • 深度优先和广度优先【栈、堆前端举例】
  • MACPA:fMRI连接性分析的新工具
  • idea快捷键
  • GEE :利用MODIS土地分类数据监测指定区域2001-2024年农作物的时序面积
  • 用HTML写一个动态的的电子相册实战详细案例
  • 论文阅读翻译之Deep reinforcement learning from human preferences
  • 分布式风电电池储能系统
  • ucx 编译安装检验方式备忘
  • 大模型笔记02--基于fastgpt和oneapi构建大模型应用平台
  • Axure高效打造大屏可视化BI数据展示
  • 主成分分析(Principal Component Analysis,PCA)—无监督学习方法
  • 深度神经网络DNN、RNN、RCNN及多种机器学习金融交易策略研究|附数据代码
  • 模拟k的次方和从0-n次方
  • 最好磁吸充电宝是哪个牌子?目前公认好用磁吸充电宝排行榜!
  • 1658.将x减到0的最小操作数
  • 宠物空气净化器哪个好?希喂、352、有哈宠物空气净化器测评分享
  • 什么是死锁?怎么预防?如何解决?
  • 如何在群晖NAS中安装HA平台并实现异地控制智能家居设备实战教程
  • 90、k8s之secret+configMap
  • async和await真题
  • h5页面使用antd-modal,怎么处理居中且自然
  • Flutter-底部选择弹窗(showModalBottomSheet)
  • Ubuntu系统使用Docker部署Jupyter Notebook并实现笔记云同步