【问题标题】:Base pointer and stack pointer基指针和栈指针
【发布时间】:2012-05-03 02:50:19
【问题描述】:

鉴于这段代码:

       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 添加到 Base Pointer 以获取第一个参数的地址,然后 12 ?

我知道它们是双字,所以它们每个都是 4 个字节。所以从 ebp + 8 到 ebp + 12 是有意义的。但是为什么第一个是 ebp + 8 ?因为如果ESP指向栈顶,mov ebp,esp表示EBP指向栈顶。然后我们将 4 个值压入堆栈:eax、ebx、ecx 和 edx。为什么 EBP + 8 指向第一个参数?

【问题讨论】:

    标签: assembly x86 nasm stack-pointer


    【解决方案1】:

    当函数被调用时,栈是这样的:

    +-------------+
    | 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 系列肯定是这样),所以堆栈的顶部将具有最低的内存地址。

    【讨论】:

    • 哇好干净!谢谢,这很有帮助!我想关键是堆栈向下增长!很高兴知道 !你让我开心。
    【解决方案2】:

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

    【讨论】:

    • 我从来没有想过返回地址被压入堆栈!非常感谢
    猜你喜欢
    • 2021-09-17
    • 2011-12-09
    • 2015-05-19
    • 2010-11-26
    • 1970-01-01
    • 2016-11-09
    • 2013-01-20
    • 2012-01-18
    相关资源
    最近更新 更多