34
votes

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 ?

2

2 Answers

50
votes

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.

7
votes

Because there are two other items on the stack; the previous ebp, which you push at the beginning of this routine, and the return address, which is put on the stack by the call to the routine.