PUSH does:
ESP := ESP-4 ; for x86; -8 for x64 MEMORY[ESP]:=<operandvalue>
POP does:
<operandtarget>:=MEMORY[ESP]; ESP:=ESP+4 ; for x86; +8 for x64
It is much easier to understand what machine instructions are if you write their descriptions in pseudo-code like this. Intel reference manuals are full of such pseudo code, and it is worth your time and trouble to get them and read the details for yourself.
Regarding your specific question: your store of $ 5 at -4 (% esp) is a valid machine instruction, and the processor will execute it without complaint, but it is really extremely dangerous programming. If the processor takes a trap or interrupts immediately after this command, the state of the processor (usually) is saved "over the stack" and overwrites your value. Since interrupts occur asynchronously, the behavior you will see is that, rarely, $ 5 is lost. This makes a very complex debugging program.
"Add $ 4" puts the ESP back in place before the push command. Thus, you cannot say anything about the value that appeared in ebp, except that it is "unknown", as you suggested as one of your options.
source share