С++ CodeBlocks разборки; Слишком много кода?

Я запустил отладчик в CodeBlocks и просмотрел окно дизассемблирования.

Полный исходный код для отлаживаемой программы следующий:

int main(){}

и код сборки, который я видел в окне, был следующим:

00401020    push   %ebp
00401021    mov    %esp,%ebp
00401023    push   %ebx
00401024    sub    $0x34,%esp
00401027    movl   $0x401150,(%esp)
0040102E    call   0x401984 <[email protected]>
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 <[email protected]>
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

Нормально ли получить этот код сборки из небольшого кода на С++?

По нормали, я имею в виду, что это близко к среднему количеству кода сборки, который компилятор MinGw генерирует относительно количества исходного кода С++, приведенного выше?

Ответ 1

Да, это довольно типичный код запуска/завершения работы.

Перед запуском main должно произойти несколько вещей:

  • stdin/stdout/stderr открывается.
  • cin/cout/cerr/clog открывается, ссылаясь на stdin/stdout/stderr
  • Любые статические объекты, которые вы определяете, инициализируются
  • командная строка получает синтаксический анализ для создания argc/argv
  • среда получает (возможно)

Аналогично, после выхода main должно произойти еще несколько вещей:

  • Все, что настроено с помощью atexit, запускается
  • Ваши статические объекты уничтожаются
  • cin/cout/cerr/clog уничтожаются
  • все открытые выходные потоки очищаются и закрываются.
  • все открытые входные потоки закрываются.

В зависимости от платформы может быть еще несколько вещей, таких как настройка некоторых обработчиков исключений по умолчанию (для исключений С++, некоторых исключений для конкретной платформы или для обоих).

Обратите внимание, что большинство из них - это фиксированный код, который привязывается по существу к каждой программе независимо от того, что она делает или не содержит. Теоретически они могут использовать некоторые трюки (например, "слабые внешние" ), чтобы избежать связывания в каком-либо из этого кода, когда это не требуется, но большая часть того, что выше, используется так близко к универсальному (и код для его обработки достаточно тривиальным), что довольно редко приходится беспокоиться о любой работе по устранению этого небольшого количества кода, даже если он не будет использоваться (например, ваш случай, когда ничего не используется вообще).

Обратите внимание, что вы указали код запуска/завершения работы. Он связан с вашей программой традиционно из файла с именем вроде crt0 (наряду с, возможно, некоторыми дополнительными файлами).

Если вы просмотрите файл для кода, сгенерированного для самого main, вы, вероятно, обнаружите, что он намного короче - возможно, как короткий, так и простой, как только ret. Это может быть настолько крошечным, что вы упустили тот факт, что он там вообще, хотя.

Ответ 2

Этот call 0x401318 <main>

- это то, что вы решили в коде. main() - это функция, и рядом с ней есть код, который часто называется чем-то вроде __start и __end.

То, что вы видите, частично составляет код поддержки CRT в __start и очистку после этого в __end.