Объясните странную сборку пустой функции C `main` компилятором Visual C ++ - PullRequest
14 голосов
/ 29 июля 2010

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

//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   
  1. с какой стати она резервирует 192 байта для функции, в которой нет переменных
  2. Что происходит с четырьмя строками: строка 1, строка 2, строка 3, строка 4? что он пытается сделать и ПОЧЕМУ?

Ответы [ 2 ]

18 голосов
/ 29 июля 2010

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

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

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

15 голосов
/ 29 июля 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...