返回介绍

CPU 阿甘:函数调用的秘密

发布于 2025-01-22 00:38:44 字数 1351 浏览 0 评论 0 收藏 0

我是 CPU 阿甘, 上次我给大家承诺过,要讲一讲函数调用的秘密, 这个确实有点复杂, 想透彻的理解机器代码层面的函数调用不容易。

我也是从无数的指令中悟出这个函数调用的秘密的, 所以慢慢来,不要急。 放松心情, 慢慢的品味, 你可能需要多看几遍才能明白。

但是你一旦理解了,绝对物超所值,因为你会了解到汇编,寄存器,指针,以及他们在一起到底是怎么工作的。

首先, 一个程序一条一条的指令都的老老实实的放在内存的一个地方,这个地方是 Linux 老大分配的, 我干涉不了, 但是这些指令都是我打电话给硬盘, 让他给运输到内存的。

然后 Linux 老大就会告诉我程序的入口点, 其实就是第一条指令的存放地址, 我就打电话问内存要这个指令, 取到指令以后就开始执行。 这些指令当中无非有这么几类: 1. 把数据从内存加载我的寄存器里 什么? 你不知道啥是寄存器? 寄存器就是我内部的一个临时的数据存储空间了 2. 对寄存器的数据进行运算, 例如把两个寄存器的数加起来 3. 把我寄存器的数据再写到内存里

但是我一旦遇到像这样的指令。 "把寄存器 ebp 的值压到栈里去“ 我就知道好戏要上场了, 函数调用就会开始。

我们这些 x86 体系的机器有个特点,就是每个函数调用都会创建一个所谓的“帧”

哈哈, 不要被这些术语吓坏, 其实帧也就是我哥们内存中的一段连续的空间而已。 像这样:

这又是在干嘛?

这其实就相当于把 x 的指针 &x 和 y 的指针 &y ,放到了特定的地方,准备着要做什么事情 , 可能要调用函数了。

所以,所谓的指针就是地址而已。

我猜程序员写的代码应该是这样: int x = 10; int y = 20; int sum= add(&x, &y); ​ 接下来的指令是这样: “调用函数 add”

我看到这样的函数就需要特别小心, 因为我必须要找到 add 函数返回以后的那条指令的地址, 把它也压到栈里去。

int x = 10;
int y = 20;
int sum = add(&x, &y);
printf("the sum is %d\n", sum);

假设这条指令的地址是 100

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文