I'm trying to understand more about stack pointer's behavior through function calls, and I'm not sure I understand what happens when we call and return from a function.
Assuming I have this main program:
int main()
{
demo();
return 0;
}
And demo is defined like this:
void demo()
{
}
I'm using VS2019, and when I debug I inspect the following SP values through time with respect to the assembly code (example for values for debug session):
- Before entering
demo
-
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1D4F ESP?=?008FFAB8 EBP?=?008FFBA8 EFL?=?00000246
demo();
00DD1D4F call _bar (0DD1410h)
- Step into
call
-
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1410 ESP?=?008FFAB4 EBP?=?008FFBA8 EFL?=?00000246
and in assembly the position is:
00DD1410 jmp demo (0DD1A30h)
- One step into
jmp
function -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A30 ESP?=?008FFAB4 EBP?=?008FFBA8 EFL?=?00000246
The function flow in assembly:
void demo()
{
(1) 00DD1A30 push ebp
(2) 00DD1A31 mov ebp,esp
(3) 00DD1A33 sub esp,0C0h
(4) 00DD1A39 push ebx
(5) 00DD1A3A push esi
(6) 00DD1A3B push edi
(7) 00DD1A3C lea edi,[ebp-0C0h]
(8) 00DD1A42 mov ecx,30h
(9) 00DD1A47 mov eax,0CCCCCCCCh
(10)00DD1A4C rep stos dword ptr es:[edi]
(11)00DD1A4E mov ecx,offset _2D317A6C_scratch_pad@c (0DDD00Ch)
(12)00DD1A53 call @__CheckForDebuggerJustMyCode@4 (0DD134Dh)
}
- Step into (1), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A31 ESP?=?008FFAB0 EBP?=?008FFBA8 EFL?=?00000246
- Step into (2), changes -
AX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A33 ESP?=?008FFAB0 EBP?=?008FFAB0 EFL?=?00000246
- Step into (3), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A39 ESP?=?008FF9F0 EBP?=?008FFAB0 EFL?=?00000206
- Step into (4), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A3A ESP?=?008FF9EC EBP?=?008FFAB0 EFL?=?00000206
- Step into (5), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A3B ESP?=?008FF9E8 EBP?=?008FFAB0 EFL?=?00000206
- Step into (6), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A3C ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
- Step into (7), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FF9F0 EIP?=?00DD1A42 ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
- Step into (8), changes -
EAX?=?00DDD006 EBX?=?00608000 ECX?=?00000030 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FF9F0 EIP?=?00DD1A47 ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
- Step into (9), changes -
EAX?=?CCCCCCCC EBX?=?00608000 ECX?=?00000030 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FF9F0 EIP?=?00DD1A4C ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
- Step OVER into (10), changes-
EAX?=?CCCCCCCC EBX?=?00608000 ECX?=?00000000 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFAB0 EIP?=?00DD1A4E ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
- Step over (11), changes-
EAX?=?CCCCCCCC EBX?=?00608000 ECX?=?00DDD00C EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFAB0 EIP?=?00DD1A53 ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
- Step into (12), changes-
EAX?=?CCCCCCCC EBX?=?00608000 ECX?=?00DDD00C EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFAB0 EIP?=?00DD134D ESP?=?008FF9E0 EBP?=?008FFAB0 EFL?=?00000206
My questions are:
- Before entering demo,
ESP = 008FFAB8
, and then ESP
changed - ESP?=?008FFAB4
. What inserted in those 4 bytes that caused the stack pointer to increase (downwards)?
- Is the EBP is essentially the 'Frame Pointer'? and in the 4 bytes underneath it we can assume the return address resides? and then the function's parameters?
- Is the diff
EBP - ESP
results in the memory allocated for the locals of the functions?
- Is every time we push something inside the
demo
scope (as done in (1)) then the stack pointer will increase?
- Will appreciate explanation on what exactly happens in the stack in steps (1)-(9).
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…