函数调用后栈的内容

标签 c assembly gdb stack cpu-registers

我正在读一本书,其中解释了调用函数时ebpeip 寄存器如何工作。提供下图:

enter image description here

这里array是一个局部函数变量。函数参数为 ab。实际的 C 代码如下所示:

#include <stdio.h>

void function(int a, int b)
{
   int array[8];
}

int main()
{
   function(1,2);
   return 0;
}

我使用 gcc -m32 -g function.c 进行编译,并在 gdb 中运行该程序。命令 disas main 显示(跳过了一些行):

0x08048474 :    push   $0x2
0x08048476 :    push   $0x1
0x08048478 :    call   0x804843b 
0x0804847d :    add    $0x10,%esp

function() 的前几条指令和最后几条指令是:

0x0804843b :    push   %ebp
0x0804843c :    mov    %esp,%ebp
0x0804843e :    sub    $0x38,%esp
0x08048441 :    mov    %gs:0x14,%eax
0x08048447 :    mov    %eax,-0xc(%ebp)
0x0804844a :    xor    %eax,%eax
0x0804844c :    nop
    ...
0x0804845e :    leave  
0x0804845f :    ret

当我检查ebp的内容时:

(gdb) x/4xw $ebp
0xffffcd48:     0xffffcd68      0x0804847d      0x00000001     0x00000002    

据我了解,在堆栈中,ebp 后面应该跟有返回位置 0x0804847d 以及函数参数 0x000000010x00000002 。但是我不知道0xffffcd68是什么。这是ebp的地址吗?

最佳答案

它是函数开头的ebp的值。
这是 push %ebp 的结果,而且 x86 堆栈是完全降序的。

它是调用者帧指针。

<小时/>

请注意,编译器更新处理堆栈的方式比书籍作者更新书籍的方式要频繁得多。
特别是:对齐、帧指针遗漏、RVO、隐式参数等可能会让您感到困惑。

关于函数调用后栈的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53461045/

相关文章:

Linux vi 中的 C 编程

c - 如何在 c 中声明具有非常量值的二维数组?

c - 使数组读取文件并存储所有数据

assembly - 为什么在 x86 汇编中 left 会执行 "mov esp,ebp"?

debugging - 通过openocd和gdb调试stm32f407时,Rust调试不会在断点处停止

c++ - C/C++ 中的正则表达式库

assembly - 浮点按位运算的用处

assembly - multboot header 中校验和的用途是什么?

macos - 如何让 gdb 在 OSX 10.11 El Capitan 下使用 macports 工作?

c - 在不断增长的日志文件上使用 tcpdump