Я пытаюсь выучить язык ассемблера на примере, или компиляции простых файлов C с GCC, используя опцию -S, синтаксиса интел и CFI вызовы инвалидов (любой другой свободный путь чрезвычайно запутаннымGCC компилируется сборки
My C файл буквально int main() {return 0;}
, но GCC выплевывает это:
.file "simpleCTest.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
push ebp
mov ebp, esp
and esp, -16
call ___main
mov eax, 0
leave
ret
.ident "GCC: (GNU) 5.3.0"
Мой реальный вопрос почему основная функция имеет каких-либо инструкций процессора (push edp
, mov edp, esp
и т.д.) Являются ли эти даже нужно (я предполагаю, что это будет? способ управления данными для подготовки/закрытия программ, но я не уверен)? Почему? Sn't это просто выпустить заявление ret
после основной функции? Также почему существуют две основные функции (_main & ___main)?
Подводя итог, почему это не так?
.def _main
_main:
mov eax, 0 ;(for return integer)
ret
Включить оптимизацию ('-O2'). Обратите внимание, что 'main' является особенным, вам может быть лучше, если вы делаете' int foo() {return 0;} 'Также, попытка понять код, сгенерированный компилятором, не всегда легко. – Jester
Похоже, вы на Windows? Причина в том, что '___ main' вызывается - это вызов любых зарегистрированных статических конструкторов. 'и esp, -16' состоит в том, чтобы убедиться, что стек равен 16 байтам до вызова' ___ main'. Esp/ebp/leave часто являются стандартными кодовыми табличками для стековых кадров. Может пригодиться при отсутствии данных об удалении стека при использовании с отладчиком, но не требуется. –
Есть несколько хороших ссылок в [x86 tag wiki] (http://stackoverflow.com/tags/x86/info), которые могут показаться вам интересными. –