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 thenESP
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).