函数调用后堆栈的内容

Contents of stack after function call

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

这里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   [=26=]x2
0x08048476 :    push   [=26=]x1
0x08048478 :    call   0x804843b 
0x0804847d :    add    [=26=]x10,%esp

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

0x0804843b :    push   %ebp
0x0804843c :    mov    %esp,%ebp
0x0804843e :    sub    [=27=]x38,%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 后面应该是 return 位置 0x0804847d 和函数参数 0x000000010x00000002。但是我不知道什么是 0xffffcd68。这是ebp的地址吗?

是函数开头ebp的值
这是 push %ebp 和 x86 堆栈完全降序这一事实的结果。

它是调用者帧指针。


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