I am having trouble grasping the answer in this stackoverflow thread. https://stackoverflow.com/a/1395646
In the middle of the answer it says Most function prologs look something like:...
As I understand the instructions in the mentioned answer --> The first instruction pushes ebp on to the stack. Then we move esp into ebp. And lastly we subract 20 from esp, making esp point 20 addresses down from where it was.
From the instructions above I visualize the stack as this.
high address
__________________________
| (an address) | <-- ebp
..........................
..........................
| | <-- esp points to an address 20
| | bytes lower
| |
| |
| |
|________________________|
low address
If this visualization is correct, how can you then push anything on the stack when you dont even have any reference to where the next local variable can be placed?
The 'low address' is where the stackpointer ESP
is. Pushing anything to the stack stores it beneath this address.
Storing a local variable would use a EBP
relative addressing mode with a negative offset.
In your example there's a 20 byte difference between EBP
and ESP
.
In the absense of any pushes, MOV
ing to where ESP
points fills the lowest 4 bytes of that 20-byte area. On the contrary, the first PUSH
will store beneath that 20-byte area. Only the PUSH
instruction will lower the stackpointer beforehand. MOV
uses ESP
as is.
The following store to the same address in memory:
mov [ebp-20], eax
mov [esp], eax
Now, if we push
some new datum to the stack, then ESP
changes but EBP
remains, and so the following is true:
push ebx <<< The first push
mov eax, [ebp-20] <<< Still at -20
mov edx, [esp+4] <<< Now at +4
EAX
and EDX
are equal to each other.