Wat is tussen ESP en EBP?

Rechts, ik weet zeker dat dit vele malen impliciet wordt beantwoord, maar ik lijk niet in staat om er helemaal bij te komen.

Als u een (x86) stapel trace (zeg, kijkend naar het in WINDBG), en u kijkt naar de registers, wat betekent het voor EBP en ESP-waarden om X Bytes uit elkaar te zijn?

Links:

Om een ​​voorbeeld van een recent stack-trace te geven, had ik:

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

Waarden van ESP 1ac5ee8c– EBP 1ac5eef4= 104 BYTES VERSCHIL. Dus wat zit er?


Antwoord 1, Autoriteit 100%

ESP is de huidige stapelwijzer. EBP is de basisaanwijzer voor het huidige stapelframe.

Wanneer u een functie belt, is typisch ruimte gereserveerd op de stapel voor lokale variabelen. Deze ruimte wordt meestal verwezen via EBP (alle lokale variabelen en functieparameters zijn een bekende constante offset van dit register voor de duur van de functie-oproep.) ESP, anderzijds zal veranderen tijdens de functie-oproep als andere functies worden genoemd, of als tijdelijke stapelruimte wordt gebruikt voor gedeeltelijke bedieningsresultaten.

Merk op dat de meeste compilers tegenwoordig een optie hebben om alle lokale variabelen door ESP te verwijzen. Dit maakt EBP vrij voor gebruik als algemene register.

In het algemeen, wanneer u naar de demontage-code aan de bovenkant van een functie kijkt, ziet u zoiets:

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

Dus EBP wijst naar de bovenkant van uw stapel voor dit frame en zal het ESP naar de volgende beschikbare byte op de stapel wijzen. (Stapels meestal – maar hoeven niet – groeien in het geheugen.)


Antwoord 2

Meestal is deze ruimte gereserveerd voor lokale variabelen die uiteindelijk op de stapel worden opgeslagen. Aan het begin van de functie wordt ESPverlaagd met de juiste waarde.

In jouw geval zijn er 104 bytes aan locals in de functie.

Other episodes