У меня есть простая рекурсивная функция RCompare (), которая вызывает более сложную функцию Compare (), которая возвращается перед рекурсивным вызовом. Каждый уровень рекурсии использует 248 байтов стекового пространства, что кажется намного больше, чем следовало бы. Вот рекурсивная функция:
void CMList::RCompare(MP n1) // RECURSIVE and Looping compare function
{
auto MP ne=n1->mf;
while(StkAvl() && Compare(n1=ne->mb))
RCompare(n1); // Recursive call !
}
StkAvl () - это простая функция проверки пространства стека, которая сравнивает адрес автоматической переменной со значением адреса в конце стека, хранящегося в статической переменной.
Мне кажется, что единственное, что добавляется в стек в каждой рекурсии, это две переменные-указатели (MP - указатель на структуру) и вещи, которые хранит один вызов функции, несколько сохраненных регистров, базовый указатель, адрес возврата и т. д., все 32-битные (4 байта) значения. Неужели нет 248 байтов?
Я не знаю, как реально осмыслить стек в Visual Studio 2008.
Спасибо
Добавлена разборка:
CMList::RCompare:
0043E000 push ebp
0043E001 mov ebp,esp
0043E003 sub esp,0E4h
0043E009 push ebx
0043E00A push esi
0043E00B push edi
0043E00C push ecx
0043E00D lea edi,[ebp-0E4h]
0043E013 mov ecx,39h
0043E018 mov eax,0CCCCCCCCh
0043E01D rep stos dword ptr es:[edi]
0043E01F pop ecx
0043E020 mov dword ptr [ebp-8],edx
0043E023 mov dword ptr [ebp-14h],ecx
0043E026 mov eax,dword ptr [n1]
0043E029 mov ecx,dword ptr [eax+20h]
0043E02C mov dword ptr [ne],ecx
0043E02F mov ecx,dword ptr [this]
0043E032 call CMList::StkAvl (41D46Fh)
0043E037 test eax,eax
0043E039 je CMList::RCompare+63h (43E063h)
0043E03B mov eax,dword ptr [ne]
0043E03E mov ecx,dword ptr [eax+1Ch]
0043E041 mov dword ptr [n1],ecx
0043E044 mov edx,dword ptr [n1]
0043E047 mov ecx,dword ptr [this]
0043E04A call CMList::Compare (41DA05h)
0043E04F movzx edx,al
0043E052 test edx,edx
0043E054 je CMList::RCompare+63h (43E063h)
0043E056 mov edx,dword ptr [n1]
0043E059 mov ecx,dword ptr [this]
0043E05C call CMList::RCompare (41EC9Dh)
0043E061 jmp CMList::RCompare+2Fh (43E02Fh)
0043E063 pop edi
0043E064 pop esi
0043E065 pop ebx
0043E066 add esp,0E4h
0043E06C cmp ebp,esp
0043E06E call @ILT+5295(__RTC_CheckEsp) (41E4B4h)
0043E073 mov esp,ebp
0043E075 pop ebp
0043E076 ret
Почему 0E4h?
Подробнее:
class mch // match node structure
{
public:
T_FSZ c1,c2; // file indexes
T_MSZ sz; // match size
enum ntyp typ; // type of node
mch *mb,*mf; // pointers to next and previous match nodes
};
typedef mch * MP; // for use in casting (MP) x
Должен ли быть простой старый указатель, верно? Те же самые указатели находятся в самой структуре, и они являются обычными 4-байтовыми указателями.
Редактировать: Добавлено:
#pragma check_stack(off)
void CMList::RCompare(MP n1) // RECURSIVE and Looping compare function
{
auto MP ne=n1->mf;
while(StkAvl() && Compare(n1=ne->mb))
RCompare(n1); // Recursive call !
} // end RCompare()
#pragma check_stack()
Но это ничего не изменило. (
Что теперь?