web-dev-qa-db-fra.com

Qu'y a-t-il entre ESP et EBP?

Bon, je suis sûr que cela est implicitement répondu à plusieurs reprises, mais il semble que je ne puisse pas tout à fait y arriver.

Si vous avez une trace de pile (x86) (par exemple, en la regardant dans WinDbg) et que vous regardez les registres, qu'est-ce que cela signifie pour EBP et ESP doivent être séparées de x octets?

Liens:

Pour donner un exemple de trace de pile récente, j'avais:

0:016> k
ChildEBP RetAddr  
1ac5ee8c 76b831bb ntdll!NtDelayExecution+0x15
1ac5eef4 76b83a8b KERNELBASE!SleepEx+0x65
1ac5ef04 0060e848 KERNELBASE!Sleep+0xf
1ac5ef10 76859d77 MyApp!application_crash::CommonUnhandledExceptionFilter+0x48 [...\applicationcrash.inc.cpp @ 47]
1ac5ef98 775a0df7 kernel32!UnhandledExceptionFilter+0x127
1ac5efa0 775a0cd4 ntdll!__RtlUserThreadStart+0x62
1ac5efb4 775a0b71 ntdll!_EH4_CallFilterFunc+0x12
1ac5efdc 77576ac9 ntdll!_except_handler4+0x8e
1ac5f000 77576a9b ntdll!ExecuteHandler2+0x26
1ac5f0b0 7754010f ntdll!ExecuteHandler+0x24
1ac5f0b0 6e8858bb ntdll!KiUserExceptionDispatcher+0xf
1ac5f400 74e68ed7 mfc80u!ATL::CSimpleStringT<wchar_t,1>::GetString [f:\dd\vctools\vc7libs\ship\atlmfc\include\atlsimpstr.h @ 548]
1ac5fec0 6e8c818e msvcr80!_NLG_Return [F:\dd\vctools\crt_bld\SELF_X86\crt\prebuild\eh\i386\lowhelpr.asm @ 73]
1ac5ff48 74e429bb mfc80u!_AfxThreadEntry+0xf2 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp @ 109]
1ac5ff80 74e42a47 msvcr80!_callthreadstartex+0x1b [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 348]
1ac5ff88 76833677 msvcr80!_threadstartex+0x66 [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 326]
1ac5ff94 77569f02 kernel32!BaseThreadInitThunk+0xe
1ac5ffd4 77569ed5 ntdll!__RtlUserThreadStart+0x70
1ac5ffec 00000000 ntdll!_RtlUserThreadStart+0x1b

0:016> r
eax=00000000 ebx=1ac5efc8 ecx=19850614 edx=00000000 esi=1ac5eed0 edi=00000000
eip=7754fd21 esp=1ac5ee8c ebp=1ac5eef4 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206

Valeurs de ESP 1ac5ee8c - EBP 1ac5eef4 = 104 octets de différence. Alors qu'y a-t-il là-dedans?

27
Martin Ba

ESP est le pointeur de pile actuel. EBP est le pointeur de base pour le cadre de pile actuel.

Lorsque vous appelez une fonction, l'espace est généralement réservé sur la pile pour les variables locales. Cet espace est généralement référencé via EBP (toutes les variables locales et les paramètres de fonction sont un décalage constant connu de ce registre pendant la durée de l'appel de fonction.) ESP, d'autre part, changera pendant l'appel de fonction au fur et à mesure que d'autres fonctions seront appelées, ou comme l'espace de pile temporaire est utilisé pour des résultats d'opération partiels.

Notez que la plupart des compilateurs de nos jours ont une option pour référencer toutes les variables locales via ESP. Cela libère EBP pour l'utiliser comme un registre à usage général.

En général, lorsque vous regardez le code de désassemblage en haut d'une fonction, vous verrez quelque chose comme ceci:

Push EBP
mov  EBP, ESP
sub  ESP, <some_number>

EBP pointera donc vers le haut de votre pile pour cette trame, et ESP pointera vers le prochain octet disponible sur la pile. (Les piles habituellement - mais pas obligatoirement - croissent dans Mémoire.)

71
user420442

Habituellement, cet espace est réservé aux variables locales qui finissent par être stockées sur la pile. Au début de la fonction, ESP est décrémenté de la valeur appropriée.

Dans votre cas, il y a 104 octets de sections locales dans la fonction.

1
Frédéric Hamidi