Given this piece of code:
swap: push ebp ; back up the base pointer, mov ebp, esp ; push the context of the registers on the stack push eax push ebx push ecx push edx mov eax, [ebp+8] ; address of the first parameter mov ebx, [ebp+12] ; address of the second parameter mov dl, [eax] mov cl, [ebx] mov [eax], cl mov [ebx], dl ; restore the context of the registers from the stack pop edx pop ecx pop ebx pop eax ; restore the ebp pop ebp ret
(This is just the method. Previously we pushed the first and the second parameter on the stack.)
My question is: why do we add 8 to the Base Pointer to get to the address of the first parameter and then 12 ?
I get the fact that they are dword so each of them are 4 bytes..so from ebp + 8 to ebp + 12 it makes sens to make. But why the first one is ebp + 8 ? Because if ESP points to the TOP of the stack, mov ebp, esp means that EBP points to the TOP of the stack. Then we push 4 values on the stack : eax, ebx, ecx and edx. Why is EBP + 8 pointing on the first parameter ?
The stack pointer always points to the top (or bottom, if you prefer) of the stack. The frame pointer always points to the frame. Stack operations (e.g., push, pop, call) do not modify the frame (in a properly operating system) or the frame pointer (ever).
The base pointer is conventionally used to mark the start of a function's stack frame, or the area of the stack managed by that function. Local variables are stored below the base pointer and above the stack pointer.
What is stack pointer? A stack pointer is a small register that stores the memory address of the last data element added to the stack or, in some cases, the first available address in the stack.
Base Pointer (BP) − The 16-bit BP register mainly helps in referencing the parameter variables passed to a subroutine. The address in SS register is combined with the offset in BP to get the location of the parameter. BP can also be combined with DI and SI as base register for special addressing.
When the function is called, the stack looks like:
+-------------+ | Parameter 2 | +-------------+ | Parameter 1 | +-------------+ | Return Addr | <-- esp +-------------+
then after the "stack frame" is set up:
+-------------+ | Parameter 2 | <-- [ebp + 12] +-------------+ | Parameter 1 | <-- [ebp + 8] +-------------+ | Return Addr | +-------------+ | saved ebp | <-- ebp +-------------+ <-- esp
Now the context is saved:
+-------------+ | Parameter 2 | <-- [ebp + 12] +-------------+ | Parameter 1 | <-- [ebp + 8] +-------------+ | Return Addr | +-------------+ | saved ebp | <-- ebp +-------------+ | saved eax | +-------------+ | saved ebx | +-------------+ | saved ecx | +-------------+ | saved edx | <-- esp +-------------+
Don't forget that on many systems the stack grows downward (and that is definitely true of the x86 family), so the top of the stack will have the lowest memory address.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With