ti-enxame.com

O que há entre ESP e EBP?

Certo, tenho certeza de que isso é respondido implicitamente muitas vezes, mas parece que não sou capaz de chegar a isso.

Se você tem um rastreamento de pilha (x86) (digamos, olhando para ele no WinDbg) e observa os registros, o que significa para EBP e ESP separados por x bytes?

Ligações:

Para dar um exemplo de um rastreamento de pilha recente, tive:

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

Valores de ESP 1ac5ee8c - EBP 1ac5eef4 = 104 bytes de diferença. Então o que há lá?

27
Martin Ba

ESP é o ponteiro atual da pilha. EBP é o ponteiro base para o quadro de pilha atual.

Quando você chama uma função, normalmente o espaço é reservado na pilha para variáveis ​​locais. Esse espaço geralmente é referenciado via EBP (todas as variáveis ​​locais e parâmetros de função são um deslocamento constante conhecido desse registro durante a chamada de função.) O ESP, por outro lado, muda durante a chamada de função à medida que outras funções são chamadas, ou como espaço de pilha temporário é usado para resultados parciais da operação.

Observe que a maioria dos compiladores hoje em dia tem uma opção para referenciar todas as variáveis ​​locais por meio do ESP. Isso libera o EBP para uso como um registro de uso geral.

Em geral, quando você olha para o código de desmontagem na parte superior de uma função, verá algo assim:

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

Portanto, o EBP apontará para o topo da sua pilha para esse quadro e ESP apontará para o próximo byte disponível na pilha. (As pilhas geralmente - mas não precisam - crescem em memória.)

71
user420442

Normalmente, esse espaço é reservado para variáveis ​​locais que acabam armazenadas na pilha. No início da função, ESP é diminuído pelo valor apropriado.

No seu caso, existem 104 bytes de locais na função.

1
Frédéric Hamidi