Почему так много места в стеке?
этот вопрос исходит из ответа на вопрос переполнения стека почему в книгах говорится:"компилятор выделяет пространство для переменных в памяти"?, где я попытался продемонстрировать OP, что происходит, когда вы выделяете переменную в стеке и как компилятор генерирует код, который знает размер выделяемой памяти. По-видимому, компилятор выделяет гораздо больше места, чем требуется.
однако при компиляции следующего
#include <iostream>
using namespace std;
int main()
{
int foo;
return 0;
}
вы получаете следующий вывод ассемблера с Visual C++ 2012 скомпилирован в режиме отладки без оптимизации:
int main()
{
00A31CC0 push ebp
00A31CC1 mov ebp,esp
00A31CC3 sub esp,0CCh // Allocates 204 bytes here.
00A31CC9 push ebx
00A31CCA push esi
00A31CCB push edi
00A31CCC lea edi,[ebp-0CCh]
00A31CD2 mov ecx,33h
00A31CD7 mov eax,0CCCCCCCCh
00A31CDC rep stos dword ptr es:[edi]
int foo;
return 0;
00A31CDE xor eax,eax
}
добавить еще один int
к моей программе делает комментированную строку выше к следующему:
00B81CC3 sub esp,0D8h // Allocate 216 bytes
вопрос, поднятый @JamesKanze в моем ответе, связан с тем, почему компилятор, и, по-видимому, это не только Visual C++ (я не проводил эксперимент с другим компилятором), выделил 204 и 216 байт соответственно, где в первом случае это только нужно четыре, а во втором ему нужно только восемь?
эта программа создает 32-разрядный исполняемый файл.
С технической точки зрения, почему может потребоваться выделить 204 байта вместо всего 4?
EDIT:
вызов двух функций и создание double
и два int
в основном, вы получаете
01374493 sub esp,0E8h // 232 bytes
для той же программы, что и редактирование выше, он делает это в режиме выпуска (без оптимизации):
sub esp, 8 // Two ints
movsd QWORD PTR [esp], xmm0 // I suspect this is where my `double` goes
1 ответ:
Это дополнительное пространство генерируется параметром компиляции /Zi. Что позволяет редактировать + продолжить. Дополнительные места для локальных переменных, которые можно добавить при редактирование кода во время отладки.
вы также видите эффект /RTC, он инициализирует все локальные переменные в 0xcccccccc, так что легче диагностировать проблемы из-за забывания инициализировать переменные. Конечно, ни один из этого кода не создается в настройках конфигурации выпуска по умолчанию.