【问题标题】:C++ CodeBlocks disassembly; Way too much code?C++ CodeBlocks 反汇编;代码太多了?
【发布时间】:2014-12-17 02:34:44
【问题描述】:

我在 CodeBlocks 上运行了调试器并查看了反汇编窗口。

我调试的程序的完整源代码如下:

int main(){}

我在窗口中看到的汇编代码是这样的:

00401020    push   %ebp
00401021    mov    %esp,%ebp
00401023    push   %ebx
00401024    sub    $0x34,%esp
00401027    movl   $0x401150,(%esp)
0040102E    call   0x401984 <SetUnhandledExceptionFilter@4>
00401033    sub    $0x4,%esp
00401036    call   0x401330 <__cpu_features_init>
0040103B    call   0x401740 <fpreset>
00401040    lea    -0x10(%ebp),%eax
00401043    movl   $0x0,-0x10(%ebp)
0040104A    mov    %eax,0x10(%esp)
0040104E    mov    0x402000,%eax
00401053    movl   $0x404004,0x4(%esp)
0040105B    movl   $0x404000,(%esp)
00401062    mov    %eax,0xc(%esp)
00401066    lea    -0xc(%ebp),%eax
00401069    mov    %eax,0x8(%esp)
0040106D    call   0x40192c <__getmainargs>
00401072    mov    0x404008,%eax
00401077    test   %eax,%eax
00401079    jne    0x4010c5 <__mingw_CRTStartup+165>
0040107B    call   0x401934 <__p__fmode>
00401080    mov    0x402004,%edx
00401086    mov    %edx,(%eax)
00401088    call   0x4014f0 <_pei386_runtime_relocator>
0040108D    and    $0xfffffff0,%esp
00401090    call   0x401720 <__main>
00401095    call   0x40193c <__p__environ>
0040109A    mov    (%eax),%eax
0040109C    mov    %eax,0x8(%esp)
004010A0    mov    0x404004,%eax
004010A5    mov    %eax,0x4(%esp)
004010A9    mov    0x404000,%eax
004010AE    mov    %eax,(%esp)
004010B1    call   0x401318 <main>
004010B6    mov    %eax,%ebx
004010B8    call   0x401944 <_cexit>
004010BD    mov    %ebx,(%esp)
004010C0    call   0x40198c <ExitProcess@4>
004010C5    mov    0x4050f4,%ebx
004010CB    mov    %eax,0x402004
004010D0    mov    %eax,0x4(%esp)
004010D4    mov    0x10(%ebx),%eax
004010D7    mov    %eax,(%esp)
004010DA    call   0x40194c <_setmode>
004010DF    mov    0x404008,%eax
004010E4    mov    %eax,0x4(%esp)
004010E8    mov    0x30(%ebx),%eax
004010EB    mov    %eax,(%esp)
004010EE    call   0x40194c <_setmode>
004010F3    mov    0x404008,%eax
004010F8    mov    %eax,0x4(%esp)
004010FC    mov    0x50(%ebx),%eax
004010FF    mov    %eax,(%esp)
00401102    call   0x40194c <_setmode>
00401107    jmp    0x40107b <__mingw_CRTStartup+91>
0040110C    lea    0x0(%esi,%eiz,1),%esi

从这么少的 C++ 代码中得到这么多的汇编代码是否正常?

通常情况下,我的意思是相对于我上面提供的 C++ 源代码的数量,这接近 MinGW 编译器生成的汇编代码的平均数量吗?

【问题讨论】:

  • MinGW 将额外的东西插入main 本身,而不是像在Linux 上那样让init 函数在main 之前运行。请参阅godbolt.org/z/ardd6qbYn 了解针对 Linux 的未优化与优化 gcc -m32

标签: c++ assembly x86


【解决方案1】:

是的,这是相当典型的启动/关闭代码。

在您的main 运行之前,需要做一些事情:

  1. stdin/stdout/stderr 被打开
  2. cin/cout/cerr/clog 被打开,指的是stdin/stdout/stderr
  3. 您定义的任何静态对象都会被初始化
  4. 命令行被解析生成 argc/argv
  5. 环境被检索(可能)

同样,在您的 main 退出后,还需要发生一些事情:

  1. 使用atexit 设置的任何内容都会运行
  2. 你的静态对象被破坏了
  3. cin/cout/cerr/clog 被破坏
  4. 所有打开的输出流都被刷新和关闭
  5. 所有打开的输入流都关闭

根据平台的不同,可能还会有更多内容,例如设置一些默认异常处理程序(针对 C++ 异常、某些特定于平台的异常,或两者兼而有之)。

请注意,其中大部分是固定代码,基本上链接到每个程序,无论它包含或不包含什么。从理论上讲,他们可以使用一些技巧(例如,“弱外部”)来避免在不需要时链接某些代码,但是上面的大部分内容都非常接近普遍使用(并且处理它的代码是足够微不足道),很少会费心去做任何工作来消除这一点代码,即使它不会被使用(比如你的情况,根本没有使用任何东西)。

请注意,您所显示的 启动/关闭代码。它链接到您的程序中,通常来自一个名为 crt0 的文件(可能还有一些其他文件)。

如果您查看为main 本身生成的代码的文件,您可能会发现它要短得多- 可能就像ret 一样简短而简单。它可能太小了,以至于您根本没有意识到它就在那里。

【讨论】:

  • 谢谢你这是完美的解释!现在我所需要的只是解释我的问题所产生的半敌意:)
  • 我猜有几个因素在起作用。首先,许多被视为“太容易”的问题会产生敌意,即使它们是不容易搜索的东西。其次,相当多的人倾向于只考虑某事是否有效,而不是如何工作,并且倾向于引导其他人远离这些细节。
  • 这肯定会缩小范围。如果不是你的回答,我的心情就会太酸了。感谢您的宝贵时间并保重。
【解决方案2】:

这个call 0x401318 &lt;main&gt;

基本上是您的代码解析的内容。 main() 是一个函数,它周围有代码,通常称为__start__end

您所看到的部分相当于 __start 中的 CRT 支持代码,以及之后在 __end 中的清理。

【讨论】:

    猜你喜欢
    • 2017-08-18
    • 2011-06-16
    • 2014-06-21
    • 2013-07-21
    • 2013-06-04
    • 2019-11-20
    • 1970-01-01
    • 2015-12-21
    • 2018-05-07
    相关资源
    最近更新 更多