gcc на windows генерирует мусор? windows vs linux

Я пытаюсь выяснить, почему в Windows есть так много инструкций для той же программы, что и Linux. Поэтому я просто использовал int a=0xbeef; и printf("test\n"); в C и скомпилированы в Linux и Windows. Когда я отлаживаю и разбираю основной фрейм, я получил это: On linux:

 0x080483e4 : push %ebp 0x080483e5 : mov %esp,%ebp 0x080483e7 : and $0xfffffff0,%esp 0x080483ea : sub $0x20,%esp 0x080483ed : movl $0xbeef,0x1c(%esp) 0x080483f5 : movl $0x80484d0,(%esp) 0x080483fc : call 0x8048318  0x08048401 : leave 0x08048402 : ret 

Хорошо, это годится. Я вижу смещение movl 0x1c для esp, чтобы поместить там значение.

Но в windowsх я получил это:

 0x401290 : push %ebp 0x401291 : mov %esp,%ebp 0x401293 : sub $0x18,%esp 0x401296 : and $0xfffffff0,%esp 0x401299 : mov $0x0,%eax 0x40129e : add $0xf,%eax 0x4012a1 : add $0xf,%eax 0x4012a4 : shr $0x4,%eax 0x4012a7 : shl $0x4,%eax 0x4012aa : mov %eax,0xfffffff8(%ebp) 0x4012ad : mov 0xfffffff8(%ebp),%eax 0x4012b0 : call 0x401720  0x4012b5 : call 0x4013c0  0x4012ba : movl $0xbeef,0xfffffffc(%ebp) 0x4012c1 : movl $0x403000,(%esp,1) 0x4012c8 : call 0x401810  0x4012cd : mov $0x0,%eax 0x4012d2 : leave 0x4012d3 : ret 

Прежде всего, я не знаю, почему компилятор Windows (mingw) генерирует столько кода. Это 2x больше, чем Linux … это заставляет меня думать. И еще: с основного + 9 до основного + 37 я не вижу смысла этого кода.

Я бы поблагодарил, если кто-то ответит на это, мне просто любопытно 🙂

edit: С аргументом -O3 в linux я получил то же самое и в windowsх что-то вроде магии:

 0x401290 : push %ebp 0x401291 : mov $0x10,%eax 0x401296 : mov %esp,%ebp 0x401298 : sub $0x8,%esp 0x40129b : and $0xfffffff0,%esp 0x40129e : call 0x401700  0x4012a3 : call 0x4013a0  0x4012a8 : movl $0x403000,(%esp,1) 0x4012af : call 0x4017f0  0x4012b4 : leave 0x4012b5 : xor %eax,%eax 0x4012b7 : ret 

оставьте затем xor, затем ret. ok: D вызов _alloca и вызов __main все еще там. и я не знаю, что такое 0x401291 : mov $0x10,%eax здесь: D

    Кажется, вы компилируете старую версию gc 3.x, вам лучше обновиться. Новые версии не вызывают alloca . Я подозреваю, что конкретная версия alloca может использовать соглашение о регистре, поэтому mov 0x10,%eax , вероятно, настраивает аргумент для этого вызова.

    __main – это функция запуска, определенная в crtbegin.o которая выполняет глобальные конструкторы и регистрирует функцию, использующую atexit которая будет запускать глобальные деструкторы.

    Также обратите внимание, что main средство получает специальную обработку, такую ​​как код выравнивания стека и вышеупомянутую инициализацию. Это может быть хорошей идеей вместо сравнения «простой» функции, если вас просто интересуют проблемы генерации кода.

    Один замечает, что в верхнем примере компилятор вызывает puts, а в нижнем – printf. Я бы заподозрил, что оптимизация включена в верхнем примере, но не в нижнем примере.

    Это также может быть отладочная версия без отладки.