【问题标题】:How many bytes does the function need?该函数需要多少字节?
【发布时间】:2011-12-02 21:13:06
【问题描述】:
int main(){
   int i;
}

调用函数后,我在 gdb 中执行了 $ebp-$esp,它给了我 4。但是旧的 ebp 呢?我可以认为这个函数在堆栈上需要 8 个字节吗? int 为 4 个字节,旧的ebp 为 4 个字节。

注意-我使用-mpreferred-stack-boundary=2 -march=i386构建它

【问题讨论】:

  • 在反汇编器中查看。
  • 如果没有完整的编译器详细信息,就无法回答这个问题。
  • 一个不错的问题,但你为什么想知道?
  • @DanFego 你为什么要知道他为什么要知道?
  • @SethCarnegie:因为通常当人们提出的问题最终得到诸如“它取决于编译器”之类的答案时,他们一开始就试图解决错误的问题。 :)

标签: c


【解决方案1】:

完全取决于编译器如何决定优化函数。一些优化编译器可能会将此函数构建为类似于“main: ret”的内容,导致它根本不使用堆栈空间。

【讨论】:

  • 保存返回地址,对吧? (我认为返回地址在逻辑上是在被调用函数的框架中)。
  • 但是在栈上我们是不是认为它在调用者的框架中,而被调用者的框架是从推送旧的ebo开始的?
【解决方案2】:

假设您在没有优化的情况下进行编译,则不会计算旧的 ebp,因为在旧的 ebp 被压入堆栈后,esp 会被复制到 ebp。我认为您看到的是 gcc 保存 ecx 虽然我不知道为什么会这样。

【讨论】:

    【解决方案3】:

    该函数需要多少内存将完全取决于您使用的编译器。这是使用 gcc 4.6.2 和编译命令对上述代码的反汇编:

    gcc -mpreferred-stack-boundary=2 -march=i386 -m32 -o test test.c
    
       0x08048394 <+0>: push   ebp
       0x08048395 <+1>: mov    ebp,esp
       0x08048397 <+3>: pop    ebp
       0x08048398 <+4>: ret
    

    很明显,i 被忽略了,因为它根本没有被使用。因此,堆栈上有 4 个字节用于call 推送的返回地址,另外 4 个字节用于保留ebp

    如您所料,如果您使用 -O1 编译标志启用轻微优化,它将变为:

       0x08048394 <+0>: ret
    

    由于根本不需要堆栈帧,main 什么都不做。

    【讨论】:

    • 但我认为返回地址没有保存在被调用者的框架中。对吗?
    • @user986424:我只是说明从调用到完成执行函数需要多少字节的堆栈内存。这就是为什么我这样说的原因,你喜欢怎么算。这还不包括在您到达 main 或 .text 部分本身之前发生的所有其他事情。
    猜你喜欢
    • 1970-01-01
    • 2019-05-04
    • 2011-01-27
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多