So we have the following code, setting up for a function call with its arguments, its main body omitted (etc etc etc), and then the popping at the end of the function.
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl 8(%ebp), %ebx
movl 12(%ebp), %ecx
etc
etc
etc
//end of function
popl %ebx
popl %ebp
Here's what I (think) I understand.
Suppose we have %esp pointing to memory address 100.
pushl %ebp
So this essentially makes %ebp point to where %esp points (memory address 100) + 4. So now %ebp points to memory address 104. This leaves our current memory state looking like so:
----------
|100|%esp
|104|%ebp
----------
Then we have the next line of code:
movl %esp, %ebp
So from what I understand, ebp now pointers to memory address 100. I have a little intuition as to why we do this step, but my confusion is the next line:
pushl %ebx
What is the purpose of pushing ebx, which I assume will then point to memory address 104? I have a vague idea of how the space right below ebp (104) is supposed to be a reference to an "old stack pointer," so I can see why the next 2 lines add 8 and 12 to ebp to be the "arguments" of our function, rather than 4 and 8.
But I'm confused as to why we push ebx onto the stack, first.
I also do not understand popping, and why we pop ebx and ebp?
Talking to someone about this before he had to sleep, he mentioned that we have no reference to the fact that our stack pointer was at 100 -- until we pop ebp back. Now, I thought ebp's value was 100, so I don't understand the point he was trying to make.
So to clarify:
Is my understanding thus far correct?
Why do we push ebx onto the stack?
What is this "reference to the old stack pointer" that lives right below ebp? Is that the ebx that we push?
Is there something I'm not understanding, like some sort of difference between the ebx that we push, and the ebx in the line right after (our argument)? Is there a difference between the ebp that gets pushed and the ebp in the line right after?
Why are we popping at the end?
I apologize if this is difficult to understand. I understand similar questions have been asked about this, but I'm trying to intuitively understand and picture what exactly is going on in a function call in a way that makes sense to me.
Note: I edited some important things regarding my understanding of what's going on, particularly with regards to ebp.
push
instructions put the contents of the given register on the stack, it doesn't make the registers "point" to anything. Also, the stack grows downwards. – Some programmer dude