3

为了更好地理解二进制文件,我准备了一个小的 c++ 示例并使用 gdb 反汇编并查找机器代码。

函数调用main()函数:func()

int func(void)
{
    int a;
    int b;
    int c;
    int d;
    d = 4;
    c = 3;
    b = 2;
    a = 1;
    return 0;
}

该项目使用 g++ 编译,保留调试信息。接下来使用gdb对源码进行反汇编。我得到的func()看起来像:

0x00000000004004cc <+0>:    push   %rbp
0x00000000004004cd <+1>:    mov    %rsp,%rbp
0x00000000004004d0 <+4>:    movl   $0x4,-0x10(%rbp)
0x00000000004004d7 <+11>:   movl   $0x3,-0xc(%rbp)
0x00000000004004de <+18>:   movl   $0x2,-0x8(%rbp)
0x00000000004004e5 <+25>:   movl   $0x1,-0x4(%rbp)
0x00000000004004ec <+32>:   mov    $0x0,%eax
0x00000000004004f1 <+37>:   pop    %rbp
0x00000000004004f2 <+38>:   retq

现在我的问题是我希望堆栈指针应该移动 16 个字节到相对于基指针的较低地址,因为每个整数值需要 4 个字节。但看起来这些值是在不移动堆栈指针的情况下放入堆栈的。

我没有正确理解什么?这是编译器的问题还是汇编器省略了一些行?

最好的问候,
没有

4

1 回答 1

4

你的编译器绝对没有问题。编译器可以自由选择如何编译你的代码,并且它选择不修改堆栈指针。它没有必要这样做,因为您的函数不调用任何其他函数。如果它确实调用了另一个函数,那么它需要创建另一个堆栈帧,以便被调用者不会踩到调用者的堆栈帧。

作为一般规则,您应该避免尝试对编译器将如何编译您的代码做出任何假设。例如,你的编译器可以完全自由地优化掉你的函数体。

于 2013-02-27T12:46:49.880 回答