c++ - main in反汇编后的说明

标签 c++ assembly x86

我有一个非常简单的程序,我的目标是研究编译器如何将值推送到不同的寄存器。但是现在行为比预期的要复杂得多,至少在 Debug模式下是这样。

这是怎么回事?

#include <cstdio>

struct A
{
    int B;
    A() : B(0) { }
};

int main()
{
    A a;
    A b(a);
    printf("%d", b.B);
    printf("%d", a.B);
    return 0;
}

这是反汇编在 Visual Studio 中的样子:

int main()
{
01048210  push        ebp  
01048211  mov         ebp,esp  
01048213  sub         esp,0D8h  
01048219  push        ebx  
0104821A  push        esi  
0104821B  push        edi  
0104821C  lea         edi,[ebp-0D8h]  
01048222  mov         ecx,36h  
01048227  mov         eax,0CCCCCCCCh  
0104822C  rep stos    dword ptr es:[edi]  
    A a;
0104822E  lea         ecx,[a]  
01048231  call        A::A (104678Ah)  
    A b(a);
01048236  mov         eax,dword ptr [a]  
01048239  mov         dword ptr [b],eax  
    printf("%d", b.B);
0104823C  mov         eax,dword ptr [b]  
0104823F  push        eax  
01048240  push        offset string "%d" (1093C6Ch)  
01048245  call        @ILT+3885(_printf) (1046F32h)  
0104824A  add         esp,8  
    printf("%d", a.B);
0104824D  mov         eax,dword ptr [a]  
01048250  push        eax  
01048251  push        offset string "%d" (1093C6Ch)  
01048256  call        @ILT+3885(_printf) (1046F32h)  
0104825B  add         esp,8  
}

前几行在 answer 中有解释。 ,它们在那里保留帧指针,以便生成漂亮的堆栈跟踪。

但接下来的几行令人困惑:为什么要从 esp 中减去 216 (0D8h)?

在 main 之后但在第一行代码 A a; 之前的这些行是做什么的?


编辑:将运行时检查设置为默认后,反汇编要小得多:

int main()
{
00247110  push        ebp  
00247111  mov         ebp,esp  
00247113  sub         esp,48h  
00247116  push        ebx  
00247117  push        esi  
00247118  push        edi  
    A a;

编辑 2:在 Release模式 (/Ox) 中,a 和 b 被完全优化掉,堆栈上根本没有分配内存:

int main()
{
    A a;
    A b(a);
    printf("%d", b.B);
00B41000  push        0  
00B41002  push        0B499A0h  
00B41007  call        printf (0B4102Dh)  
    printf("%d", a.B);
00B4100C  push        0  
00B4100E  push        0B499A4h  
00B41013  call        printf (0B4102Dh)  
00B41018  add         esp,10h  
    return 0;
0127101B  xor         eax,eax  
}
0127101D  ret  

编辑 3:这是使用 gcc -m32 -O3 -mpreferred-stack-boundary=2 的结果(感谢@CodyGray)。

.LC0:
        .string "%d"
Test():
        push    0
        push    OFFSET FLAT:.LC0
        call    printf
        pop     eax
        pop     edx
        push    0
        push    OFFSET FLAT:.LC0
        call    printf
        pop     ecx
        pop     eax
        ret

最佳答案

00CC8223  sub         esp,0D8h  

为局部变量分配堆栈空间。

What are these lines after main, but before the first instruction doing?

你指的是什么?

关于c++ - main in反汇编后的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43499212/

相关文章:

C++ 嵌套命名空间错误 - 预期的类型说明符错误

c++ - 无法打开包含文件 : 'graphics.h' : No such file or directory

C++在派生类中初始化基类的const int?

assembly - 在哪里放置堆栈并加载内核

c++ - 无法为整数获得适当的输入验证

python - 有没有办法只使用 python 库生成 ELF BINARY?

c - 汇编 - js 与 ja 指令

gcc - 在 GCC 中编译 SSE 内在函数会出错

caching - 如何找到 x86 处理器的 cpu 缓存大小

windows - 具有内联 asm 的 Windows x64 平台中的 libsoxr 未编译