汇编x86 - “离开”指令

时间:2015-04-22 07:07:28

标签: c assembly

据说“离开”指令类似于:

movl %ebp, %esp
popl %ebp

我理解movl %ebp, %esp部分,并且它用于释放已存储的内存(如this question中所述)。

但是popl %ebp代码的目的是什么?

1 个答案:

答案 0 :(得分:2)

popl指令恢复基指针,movl指令恢复堆栈指针。基指针是堆栈的底部,堆栈指针是顶部。在离开指令之前,堆栈如下所示:

----Bottom of Caller's stack----
...
Caller's
Variables
...
Function Parameters
----Top of Caller's Stack/Bottom of Callee's stack----   (%ebp)
...
Callee's
Variables
...
---Bottom of Callee's stack----    (%esp)

在释放被调用者堆栈的movl %ebp %esp之后,堆栈看起来像这样:

----Bottom of Caller's stack----
...
Caller's
Variables
...
Function Parameters
----Top of Caller's Stack/Bottom of Callee's stack----   (%ebp) and (%esp)

在恢复调用者堆栈的popl %ebp之后,堆栈如下所示:

----Bottom of Caller's stack----    (%ebp)
...
Caller's
Variables
...
Function Parameters
----Top of Caller's Stack----   (%esp)

enter指令保存调用者堆栈的底部并设置基指针,以便被调用者可以分配其堆栈。

另请注意,虽然大多数C编译器都以这种方式分配堆栈(至少在优化时关闭),但如果编写汇编语言函数,则可以根据需要使用相同的堆栈帧,但是你必须确保pop堆放你push的所有东西,否则当你返回时你会跳转到垃圾邮件地址(这是因为call <somewhere>意味着{{1} }} [或push <ret address>],push %eipjmp <somewhere>表示跳转到堆栈顶部的地址[或ret]。pop %eip是保存当前指令地址的寄存器)。