Объясните странную сборку пустой функции C `main` с помощью компилятора Visual С++

Я только что заметил какой-то странный код языка ассемблера пустого основного метода.

//filename: main.c
void main()
{

}

разборка:

push        ebp  
mov         ebp,esp  
sub         esp,0C0h; why on the earth is it reserving 192 bytes?  
push        ebx  
push        esi  
push        edi  ; good compiler. Its saving ebx, esi & edi values.
lea         edi,[ebp-0C0h]  ; line 1
mov         ecx,30h  ; line 2
mov         eax,0CCCCCCCCh  ; line 3
rep stos    dword ptr es:[edi]  ; line 4


xor         eax,eax  ; returning value 0. Code following this line is explanatory.
pop         edi  ; restoring the original states of edi,esi & ebx
pop         esi  
pop         ebx  
mov         esp,ebp  
pop         ebp  
ret   
  • почему на земле он резервирует 192 байта для функции, где нет никаких переменных
  • что происходит с четырьмя строками: строка 1, строка 2, строка 3, строка 4? что он пытается сделать и ПОЧЕМУ?

Ответы

Ответ 1

Четыре строки кода, которые вы указали, - это сборка отладки, очищающая локальное пространство переменных со специальным значением "clear" (0xCCCCCCCC).

Я не уверен, почему есть 192 байта, казалось бы, мертвого пространства, но это может быть VС++, создавая какое-то защитное пространство в вашей локальной области переменных, чтобы попытаться обнаружить разбиение стека.

Вероятно, вы получите отличный результат, если вы перейдете из Debug в Release build.

Ответ 2

Грег уже объяснил, как компилятор создает код для диагностики неинициализированных локальных переменных, включенных опцией компиляции /RTCu. Значение 0xcccccccc было выбрано как отличительное и легко распознаваемое в отладчике. И для обеспечения программных бомб, когда неинициализированный указатель разыменован. И чтобы он завершал программу, когда она выполняется как код. 0xcc вполне подходит для выполнения всех этих заданий, это код операции для INT3.

Таинственные 192 байта, выделенные в фрейме стека, предназначены для поддержки функции "Редактировать + Продолжить" / "Компиляция ZI". Он позволяет редактировать код, пока активна точка останова. И добавьте локальные переменные в функцию, которые доступны 192 байта, чтобы предоставить пространство для этих добавленных локалей. Превышение этого пространства заставит среду IDE перестроить вашу программу.

Btw: это может вызвать проблему, если вы используете рекурсию в своем коде. Отладочная сборка будет бомбить с этим названием сайта намного быстрее. Обычно это не проблема, вы отлаживаетесь с практическими размерами данных.