首页 文章

基指针和堆栈指针

提问于
浏览
30

鉴于这段代码:

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

(这只是方法 . 之前我们在堆栈上推送了第一个和第二个参数 . )

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

我知道它们是dword,因此它们每个都是4个字节 . 所以从ebp 8到ebp 12它使得它变得有意义 . 但为什么第一个是ebp 8?因为如果ESP指向堆栈的顶部,那么mov ebp,esp意味着EBP指向堆栈的TOP . 然后我们在堆栈上推送4个值:eax,ebx,ecx和edx . 为什么EBP 8指向第一个参数?

2 回答

  • 5

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

    +-------------+
    | 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系列来说确实如此),因此堆栈的顶部将具有最低的内存地址 .

  • 44

    因为堆栈上还有另外两个项目;你在这个例程的开头推送的前一个ebp,以及通过调用例程放在堆栈上的返回地址 .

相关问题