Reputation: 1197
I know this is a pretty basic question, but here it goes:
I am starting to learn Assembler, and I'm trying to understand how the stack works.
At first, when I pass a value to an assembler function, I'd access it like this:
movl 4(%esp),%eax # first parameter
movl 8(%esp),%ebx # second parameter
But I then was told that it was better to do this:
push %ebp
movl %esp,%ebp
# and then I'd access the values on %ebp:
movl 8(%ebp),%eax
movl 12(%ebp),%eax
pop %ebp
Ok, what is the difference here? When I accessed the values directly from %esp, weren't they already on the stack? What's the advantage of using push to do it again?
Does anyone have a tip on a good learning tool (for dummies-type) on how to learn how stack works so one can learn on these stack pointers, return addresses and so on? I haven't found any good visual demonstration on how it works. Thanks!
Upvotes: 1
Views: 2099
Reputation: 18503
In most cases using %ebp has historical reasons: In 16-bit programs instructions like "movw 2(%sp), %ax" are not supported by x86 CPUs because x86 CPUs only support %bx, %si, %di and %bp registers for memory addressing. So in 16-bit programs you cannot use %sp so you use %bp instead.
When using a well-optimizing modern compiler you will not see the "push" and "mov %esp, %ebp" instructions any more in 32-bit code but the code will look like your first example ("4(%esp)" instead of "8(%ebp)").
Such compilers sometimes use the %ebp register for different purposes.
There is one use case where %ebp still is necessary: The alloca() function: This function reserves memory on the stack by doing a "sub %eax, %esp" (or similar) instruction. After this instruction you do not know any longer where your arguments are.
However in 32-bit code with "flat" memory layout (%ds=%ss) you may also use any other register instead of %ebp.
Upvotes: 2
Reputation: 14057
Both the difference and the why has to do with stack frames. The following link has a fairly good summary (if I do say so myself).
What is stack frame in assembly?
Upvotes: 1