【发布时间】:2021-12-26 12:40:03
【问题描述】:
我试图理解堆栈和帧指针。我有下面的简单 C 程序:
#include <stdio.h>
#include <stdlib.h>
int myfunction(int counter) {
int result = 5;
printf("myfunction %p %p %p\n", &result, &counter, __builtin_frame_address(0));
return 0;
}
int main()
{
int i;
int j;
printf("main %p %p\n", &i, __builtin_frame_address(0));
myfunction(4);
return 0;
}
当我使用 gdb 运行程序并检查以内置框架的地址开头的内存位置时,我得到以下输出:
这引起了我的困惑。我假设地址为0xbffff608 的FP 将指向堆栈的起始地址,因此我预计result 和counter 的内存地址会高于或低于FP 地址,但这是内存地址的顺序不符合我的假设,有人可以帮忙澄清一下吗?
内存地址:
- 0xbffff608(内置帧地址,我假设这是帧指针)
- 0xbffff610(计数器参数的地址)
- 0xbffff5f8(结果变量的地址)
让我困惑的是,我认为帧指针指示堆栈的起始地址,因此在这种情况下 0xbffff608 指向当前堆栈的起始地址,那么当前堆栈中的计数器和结果应该都在之后或之前开始帧指针。但是,现在情况好坏参半。 counter 的内存地址高于帧指针,而 result 的内存地址低于帧指针。如果帧指针指示堆栈的开始,那么为什么会出现这种情况?
更新:主函数反汇编
【问题讨论】:
-
Nitpick:打印指针时,应将其强制转换为 void-pointer
-
哪个系统?我无法在我的系统上复制
-
它的 linux ubuntu 32 位
-
好的,32 位系统...好吧,我不是 100% 确定我使用 64 位系统,但据我所知,32 位系统的调用约定要求调用者放置在进行函数调用之前 堆栈上的参数。这可以解释
count的位置您查看生成的程序集了吗?在通话前查找push。 -
我确实在调用
myfunction之前看到了一个推送调用$0x4是什么意思?那是被推入的参数整数 4 吗?