Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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):

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

}
  1. Step into (1), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A31 ESP?=?008FFAB0 EBP?=?008FFBA8 EFL?=?00000246
  2. Step into (2), changes -
    AX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A33 ESP?=?008FFAB0 EBP?=?008FFAB0 EFL?=?00000246
  3. Step into (3), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A39 ESP?=?008FF9F0 EBP?=?008FFAB0 EFL?=?00000206
  4. Step into (4), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A3A ESP?=?008FF9EC EBP?=?008FFAB0 EFL?=?00000206
  5. Step into (5), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A3B ESP?=?008FF9E8 EBP?=?008FFAB0 EFL?=?00000206
  6. Step into (6), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFBA8 EIP?=?00DD1A3C ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
  7. Step into (7), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00DDD006 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FF9F0 EIP?=?00DD1A42 ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
  8. Step into (8), changes - EAX?=?00DDD006 EBX?=?00608000 ECX?=?00000030 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FF9F0 EIP?=?00DD1A47 ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
  9. Step into (9), changes - EAX?=?CCCCCCCC EBX?=?00608000 ECX?=?00000030 EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FF9F0 EIP?=?00DD1A4C ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
  10. 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
  11. Step over (11), changes- EAX?=?CCCCCCCC EBX?=?00608000 ECX?=?00DDD00C EDX?=?00000001 ESI?=?00DD1023 EDI?=?008FFAB0 EIP?=?00DD1A53 ESP?=?008FF9E4 EBP?=?008FFAB0 EFL?=?00000206
  12. 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:

  1. 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)?
  2. 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?
  3. Is the diff EBP - ESP results in the memory allocated for the locals of the functions?
  4. Is every time we push something inside the demo scope (as done in (1)) then the stack pointer will increase?
  5. Will appreciate explanation on what exactly happens in the stack in steps (1)-(9).
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
128 views
Welcome To Ask or Share your Answers For Others

1 Answer

The function call instruction causes the CPU to push the return address to the stack, which is 4 bytes in this case. The function itself can also allocate more stack space.

In Visual C++, what you are seeing is that the { line represents the stack setup code in the function (the prologue). When the next instruction is the {, the call has executed, but the function prologue has not. So 4 bytes have been taken to store the return address, but any additional bytes the function wants to use have not been allocated. When you step over {, that is the function prologue which sets up the rest of the stack frame for the function.

Jabberwocky's answer provides the assembly code for the function, but doesn't really explain why you see the stack pointer decremented in two parts.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...