【问题标题】:Contents of stack after function call函数调用后栈的内容
【发布时间】:2019-04-26 21:55:37
【问题描述】:

我正在阅读一本书,它解释了在调用函数时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 : 推送 $0x2 0x08048476 : 推送 $0x1 0x08048478 : 调用 0x804843b 0x0804847d : 添加 $0x10,%esp

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

0x0804843b : 推送 %ebp 0x0804843c : 移动 %esp,%ebp 0x0804843e : 低于 $0x38,%esp 0x08048441 : 移动 %gs:0x14,%eax 0x08048447 : 移动 %eax,-0xc(%ebp) 0x0804844a : xor %eax,%eax 0x0804844c:无 ... 0x0804845e : 离开 0x0804845f : 回复

当我检查ebp的内容时:

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

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

【问题讨论】:

  • 您的书是否描述了堆栈中的 EBP 插槽是什么?
  • 简而言之:C 中没有堆栈。对于您的具体实现,请阅读 ABI,但请记住,这通常仅适用于导出的函数。
  • 你能显示function的前几条指令吗?
  • @MarkPlotnick 这本书有关于延迟槽的信息,但我还没有读过那部分。我包含了function的说明。

标签: c assembly gdb stack cpu-registers


【解决方案1】:

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

它是调用者帧指针。


请注意,编译器更新其处理堆栈的方式比书籍作者更新其书籍的频率要高得多。
特别是:对齐、帧指针省略、RVO、隐式参数等可能会让你失望。

【讨论】:

    猜你喜欢
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多