debugging visual-c++ x86 stack cpu-registers

debugging - ¿Qué hay entre ESP y EBP?



visual-c++ x86 (2)

ESP es el puntero de pila actual. EBP es el puntero base para el marco de pila actual.

Cuando llama a una función, normalmente el espacio está reservado en la pila para las variables locales. Por lo general, se hace referencia a este espacio a través de EBP (todas las variables locales y los parámetros de función son un desplazamiento constante conocido de este registro durante la llamada a la función). ESP, por otro lado, cambiará durante la llamada a la función cuando se llamen otras funciones, o como espacio de pila temporal se utiliza para resultados de operaciones parciales.

Tenga en cuenta que la mayoría de los compiladores en estos días tienen una opción para hacer referencia a todas las variables locales a través de ESP. Esto libera EBP para uso como registro de propósito general.

En general, cuando miras el código de desmontaje en la parte superior de una función, verás algo como esto:

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

Entonces, EBP apuntará a la parte superior de la pila para este marco, y ESP apuntará al siguiente byte disponible en la pila. (Las pilas generalmente, pero no tienen que hacerlo, crecen en la memoria).

Correcto, estoy seguro de que esto se responde de forma implícita muchas veces, pero parece que no puedo hacerlo.

Si tiene un seguimiento de pila (x86) (por ejemplo, mirándolo en WinDbg) y observa los registros, ¿qué significa que los valores EBP y ESP estén separados por x bytes?

Campo de golf:

  • https://stackoverflow.com/a/3699916/321013
  • https://stackoverflow.com/a/2466587/321013
  • https://stackoverflow.com/a/5738940/321013

Para dar un ejemplo de un rastro de pila reciente que tuve:

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 diferencia. Entonces, ¿qué hay allí?


Por lo general, este espacio está reservado para las variables locales que terminan almacenadas en la pila. Al inicio de la función, el valor apropiado disminuye la ESP .

En su caso, hay 104 bytes de locales en la función.