news 2026/7/18 11:58:38

[从零构建操作系统]08 函数调用时栈的底层行为解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[从零构建操作系统]08 函数调用时栈的底层行为解析


第一步:在kernel_init里安家(黄色区域)

代码位置: 右上角 kernel_init 函数开头

栈图对应: 左侧黄色的 “局部变量和数据”

  1. sub $0x10, %esp

    • 动作:也就是把栈顶指针esp往下拉 16 个字节,给kernel_init这个函数划出一块地盘(栈帧)。

  2. movl $0x1, -0x4(%ebp)

    • 动作:把数值1放入ebp往下 4 字节的地方。

    • 对应:这就是代码里的int a = 1。图中黄色区域的a=1就存在这。

  3. movl $0x2, -0x8(%ebp)

    • 动作:把数值2放入ebp往下 8 字节的地方。

    • 对应:这就是代码里的int b = 2。图中黄色区域的b=2就存在这。


第二步:准备调用test,打包行李(橙色区域)

代码位置: 右上角 call 指令上面的两行 push

栈图对应: 左侧橙色的 “参数传递”

这里有一个关键知识点:C语言函数参数入栈顺序是从右往左。

我们要调用的是 test(a, b),所以先压 b,再压 a。

  1. push -0x8(%ebp)(对应代码push b)

    • 动作:把变量b(也就是2)压入栈中。

    • 对应:图中橙色区域上方的“参数:b”

  2. push -0x4(%ebp)(对应代码push a)

    • 动作:把变量a(也就是1)压入栈中。

    • 对应:图中橙色区域下方的“参数:a”

注意:此时栈顶(esp)已经指到了“参数 a”的位置。


第三步:跳过去执行(蓝色区域)

代码位置: 右上角 10033: call 1000c <test>

栈图对应: 左侧蓝色的 “返回地址”

  1. call ...

    • 动作:CPU要去别的地方执行代码了,但它得记得回来之后该从哪接着干。所以 CPU 会自动把“下一条指令的地址”(也就是add $0x8, %esp这一行的地址)压入栈。

    • 对应:图中蓝色的“返回地址”。此时esp指向这里(图中标注的esp1)。


第四步:进入test函数,建立新家(绿色区域)

代码位置: 右下角 test 函数的开头

栈图对应: 左侧绿色的 “之前ebp”

  1. push %ebp(test函数的第一行代码)

    • 动作:test函数说:“我也要用ebp来定位我的地盘,但我不能把kernel_initebp弄丢了。” 所以先把kernel_initebp值压入栈保存起来。

    • 对应:图中绿色的“之前的ebp”

  2. mov %esp, %ebp

    • 动作:把当前的栈顶位置赋值给ebp

    • 对应:此时ebpesp都指向了绿色格子的最下沿(图中标注的ebp / esp2)。


终极解密:为什么要这么折腾?

请看右下角test函数如何取参数:

现在的ebp指向绿色的“之前ebp”。

  • 往上(高地址)走 4 个字节,是蓝色的“返回地址”。

  • 再往上走 4 个字节(+8),就是橙色的“参数 a”

  • 再往上走 4 个字节(+120xc),就是橙色的“参数 b”

对照右下角代码:

  • mov 0x8(%ebp), %edx-> 取出了a

  • mov 0xc(%ebp), %eax-> 取出了b

总结

这张图画的就是:

  1. 黄色:调用者自己存的私房钱(局部变量)。

  2. 橙色:调用者打包给被调用者的礼物(参数)。

  3. 蓝色:回家的路标(返回地址)。

  4. 绿色:被调用者用来定位的基准桩(旧 ebp)。

被调用者(test)站在绿色的位置,往回伸手(ebp + 偏移),就能拿到别人传给它的参数。

补充:x86编译器对各字段的分类

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/18 23:43:44

校招 Java 面试必看:JVM 其实就考这 3 个点(我帮你讲透)

一、校招面试为什么爱问 JVM&#xff1f;对校招来说&#xff0c;面试官并不指望你会 JVM 调优&#xff0c;他们更关心三件事&#xff1a;你知不知道 Java 程序是怎么跑起来的你遇到内存问题&#xff0c;会不会“瞎猜”你有没有基本的底层理解能力&#x1f449; 所以校招 JVM 的…

作者头像 李华
网站建设 2026/7/18 2:59:05

【高可用系统监控的设计原则与实践】

监控系统的设计原则与实践 高可用系统的监控设计需要遵循实时性、直观性和整体性原则&#xff0c;确保能快速发现、定位和解决问题。以下是具体的设计思路和实施方案&#xff1a; 实时监控与告警机制 每个节点部署Agent进行数据采集&#xff0c;包括HTTP接口、Redis、MQ和DB等关…

作者头像 李华
网站建设 2026/7/18 19:18:58

前期工作总结

任务&#xff1a;各自把前期工作总结&#xff0c;包括主要使用的模型或技术介绍&#xff0c;附上博客链接。 1. BERT模型的改进 使用模型为bge-large模型替换bert。 bge模型&#xff08;M3&#xff09;以及BGE模型使用的预训练方法RetroMAE的具体技术介绍见&#xff1a;《M3…

作者头像 李华
网站建设 2026/7/18 10:16:18

16、深入了解 Oracle Clusterware:功能、安装与管理

深入了解 Oracle Clusterware:功能、安装与管理 1. Oracle Clusterware 概述 Oracle Clusterware 是集成于 Oracle 数据库的集群管理器,能够提供管理集群数据库所需的所有功能,包括节点成员管理、组服务、全局资源管理和高可用性功能。它通过消除冗余硬件和软件环境中的单…

作者头像 李华
网站建设 2026/7/18 15:32:28

Asio网络编程入门:从零构建同步客户端与服务器

在网络编程世界中&#xff0c;Asio&#xff08;Asynchronous I/O&#xff09;是一个强大而灵活的C库&#xff0c;它提供了一套统一的异步I/O模型。无论你是刚接触网络编程&#xff0c;还是希望从其他框架转向Asio&#xff0c;本文将带你系统学习Asio的同步编程基础&#xff0c;…

作者头像 李华
网站建设 2026/7/16 18:43:55

3分钟快速上手:WhiteSur主题打造macOS风格Linux桌面完整指南

3分钟快速上手&#xff1a;WhiteSur主题打造macOS风格Linux桌面完整指南 【免费下载链接】WhiteSur-gtk-theme MacOS Big Sur like theme for Gnome desktops 项目地址: https://gitcode.com/GitHub_Trending/wh/WhiteSur-gtk-theme 厌倦了千篇一律的Linux桌面&#xff…

作者头像 李华