news 2026/2/10 15:07:04

[从零构建操作系统]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/2/5 12:10:30

折叠与影像:高端手机技术演进的两大方向

每当为大家提供丰富选择的每年购物季时段来临之际&#xff0c;高端手机市场无一例外地都会出现新品发布会密集举行以及价格作出调整的情况。众多旗舰机型之中可以发现存在两个备受关注的技术方向&#xff0c;其中一个是折叠屏方向&#xff0c;另一个是影像旗舰方向&#xff0c;…

作者头像 李华
网站建设 2026/2/8 18:40:01

智能零碳管理系统功能与实现

智能零碳管理系统旨在帮助企业有效管理和监控其碳排放&#xff0c;同时为公众用户提供有用的碳排放信息和咨询服务。本文将详细介绍该系统的功能模块与Django模型代码的实现。一、系统角色与权限总结 1. 管理员 审核企业碳排放数据&#xff08;可设置不合格提醒&#xff09; 发…

作者头像 李华
网站建设 2026/2/10 9:23:20

你是否正在经历这些知识管理的 “隐形内耗”?​

技术文档散落在语雀、GitHub、本地硬盘&#xff0c;新员工入职像 “寻宝”&#xff1b;写一份部署手册要熬 4 小时&#xff0c;修改迭代还要跨平台同步&#xff1b;搜索 “token 过期解决方案”&#xff0c;返回几十篇无关文档&#xff0c;翻半天找不到重点&#xff1b;敏感数据…

作者头像 李华
网站建设 2026/2/10 9:41:38

快速排序(Quick Sort)的“死穴”

快速排序&#xff08;Quick Sort&#xff09;的“死穴”&#xff0c;也就是它的最坏情况。简单来说&#xff0c;它的意思是&#xff1a;如果你运气不好&#xff0c;选的基准值&#xff08;Pivot&#xff09;太极端&#xff0c;快速排序就会变得非常慢&#xff0c;慢得像冒泡排序…

作者头像 李华
网站建设 2026/2/7 1:50:39

25、技术探索:Google App Engine、Zenoss与Python包管理

技术探索:Google App Engine、Zenoss与Python包管理 一、Google App Engine数据查询与路由 在Google App Engine开发中,数据查询与路由是重要的环节。以下是一段用于从数据存储中获取最后10条记录并进行处理的代码: collection = [] #grab last 10 records from datasto…

作者头像 李华
网站建设 2026/2/9 5:35:58

每日一练:流星雨

题目描述贝西听说一场非凡的流星雨即将来临&#xff1b;报告称这些流星将撞击地球并摧毁它们所碰到的任何东西。为了安全&#xff0c;她发誓要找到一个安全的位置&#xff08;一个从未被流星摧毁的地方&#xff09;。她目前在坐标平面的原点放牧&#xff0c;想要移动到一个新的…

作者头像 李华