基本指针和堆栈指针

鉴于这段代码:

       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

(这只是方法,以前我们把第一个和第二个参数放在堆栈上。)

我的问题是:为什么我们将8添加到基址指针来获取第一个参数的地址,然后是12?

我得到的事实是,他们是dword,因此他们每个人都是4字节..所以从ebp + 8到ebp + 12它使得敏感。 但为什么第一个是ebp + 8? 因为如果ESP指向堆栈的顶部,则mov ebp,esp表示EBP指向堆栈的顶部。 然后我们在栈上推入4个值:eax,ebx,ecx和edx。 为什么EBP + 8指向第一个参数?


当函数被调用时,堆栈如下所示:

+-------------+
| Parameter 2 |
+-------------+
| Parameter 1 |
+-------------+
| Return Addr |  <-- esp
+-------------+    

那么在“堆栈框架”建立之后:

+-------------+
| Parameter 2 | <-- [ebp + 12]
+-------------+
| Parameter 1 | <-- [ebp + 8]
+-------------+
| Return Addr |  
+-------------+    
| saved ebp   | <-- ebp
+-------------+ <-- esp

现在保存上下文:

+-------------+
| Parameter 2 | <-- [ebp + 12]
+-------------+
| Parameter 1 | <-- [ebp + 8]
+-------------+
| Return Addr |  
+-------------+    
| saved ebp   | <-- ebp
+-------------+ 
| saved eax   |  
+-------------+    
| saved ebx   |  
+-------------+    
| saved ecx   |  
+-------------+    
| saved edx   | <-- esp
+-------------+    

不要忘记,在许多系统中,堆栈向下增长(这对x86系列来说确实如此),因此堆栈的顶部将具有最低的内存地址。


因为堆栈上还有两个其他项目; 前一个ebp,你在这个例程的开始处推送的,以及返回地址,它通过调用例程放在堆栈上。

链接地址: http://www.djcxy.com/p/43851.html

上一篇: Base pointer and stack pointer

下一篇: Opcode and ModRM for 'call dword ptr [mem32]' question?