从汇编层看64位程序运行——栈帧(Stack Frame)的组成

通过《从汇编层看64位程序运行——栈帧(Stack Frame)的边界》《从汇编层看64位程序运行——参数传递的底层实现》《从汇编层看64位程序运行——栈上变量的rbp表达》《从汇编层看64位程序运行——函数的调用和栈平衡》这四篇的讲解,栈帧的组成基本清晰了。
首先栈帧的起始地址是:调用者函数调用子函数(call指令)前的RSP
这就意味着call指令压栈的Next RIP也属于子函数的栈帧,而通过栈向子函数传递参数的空间则属于上一个栈帧。
以下面代码为例

void foo10(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;
    e = e + 5;
    f = f + 5;
    g = g + 5;
    h = h + 5;
    i = i + 5;
    j = j + 5;
    int sum = a + b + c + d + e + f + g + h + i + j;
    sum = sum + 5;
}

int main() {
    int a = 10;
    int b = 20;
    int c = 30;
    int d = 40;
    int e = 50;
    int f = 60;
    int g = 70;
    int h = 80;
    int i = 90;
    int j = 100;
    foo10(a, b, c, d, e, f, g, h, i, j);
    return 0;
}

main函数的反汇编如下
在这里插入图片描述
foo10函数的栈帧起始地址就是代码执行到+120处(+118行执行完,但是+120行没执行)时的rsp寄存器的值。
之前+105,+109,+113和+117处的压栈空间,都是属于main函数的栈帧。
在这里插入图片描述
所以一个栈帧依次包含:

抛出一个问题:一个函数是否可以访问不是自己栈帧上的数据?
答案是可以的。
因为我们之前提过,栈帧是一个虚拟概念。人们只是借用它来方便表述函数在运行过程中的栈的变化。
比如在调用超过6个参数的函数时,子函数内部就会访问到上个栈帧中的数据,以获取第6个以外的其他参数。
在这里插入图片描述

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 12:22:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 12:22:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 12:22:01       45 阅读
  4. Python语言-面向对象

    2024-07-20 12:22:01       55 阅读

热门阅读

  1. 白骑士的PyCharm教学目录

    2024-07-20 12:22:01       18 阅读
  2. Mathematical Problem

    2024-07-20 12:22:01       15 阅读
  3. 第六章 Spring框架深入学习(2023版本IDEA)

    2024-07-20 12:22:01       14 阅读
  4. IO文件流

    2024-07-20 12:22:01       15 阅读
  5. 游戏外挂的技术实现与五年脚本开发经验分享

    2024-07-20 12:22:01       15 阅读
  6. mysql高阶知识梳理

    2024-07-20 12:22:01       15 阅读
  7. 3.设计模式--创建者模式--工厂模式

    2024-07-20 12:22:01       15 阅读
  8. npm下载的依赖包版本号怎么看

    2024-07-20 12:22:01       16 阅读
  9. 【AI工具基础】—Kylin(一)

    2024-07-20 12:22:01       17 阅读