※ You can refer the memory stack structure here(LINK)
1. Initial state
┌─────────────────────┐ → Low address / ESP
│
│Local variables
│
├───────────────────── → EBP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters
└─────────────────────┘ → High address
2. SUB ESP,0x~ / PUSH function parameters
┌─────────────────────┐ → ESP
│Parameters of new function
├─────────────────────
│
│Local variables
│
├───────────────────── → EBP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters
└─────────────────────
3. PUSH RET
┌─────────────────────┐ → ESP
│RET
├─────────────────────
│Parameters of new function
├─────────────────────
│
│Local variables
│
├───────────────────── → EBP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters
└─────────────────────┘
At this point, the program jumps to the new function.
4. PUSH EBP
┌─────────────────────┐ → ESP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters of new function
├─────────────────────
│
│Local variables
│
├───────────────────── → EBP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters
└─────────────────────┘
※ The SFP(Stack Frame Pointer) stores the current EBP value.
5. MOV EBP, ESP
┌─────────────────────┐ → EBP | ESP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters of new function
├─────────────────────
│
│Local variables
│
├─────────────────────
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters
└─────────────────────┘
6. SUB ESP,0x~ / PUSH local variables
┌─────────────────────┐ → ESP
│
│Local variables of new function
│
├───────────────────── → EBP
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters of new function
├─────────────────────
│
│Local variables
│
├─────────────────────
│SFP
├─────────────────────
│RET
├─────────────────────
│Parameters
└─────────────────────┘
And Here is the post that is changes of stack when exiting a function(Link).