汇编中有关push ebp和pop ebp指令的说明 [英] explanation about push ebp and pop ebp instruction in assembly

查看:434
本文介绍了汇编中有关push ebp和pop ebp指令的说明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在组装中使用了堆栈,但是我不知道关于push ebp和pop ebp的想法.

i used stack in assembly but i didn't got idea about push ebp and pop ebp.

.intel_syntax noprefix

.include "console.i"

.text

askl:   .asciz  "Enter length: "
askb:   .asciz  "Enter breadth: "
ans:    .asciz  "Perimeter = "

_entry:

    push    ebp     # establishing stack-frame
    mov ebp, esp
    sub esp, 12

    Prompt  askl
    GetInt  [ebp-4]     # length
    Prompt  askb
    GetInt  [ebp-8]     # breadth

    mov eax, [ebp-4]    # eax = l
    add eax, [ebp-8]    # eax = l + b
    add eax, eax    # eax = 2 * (l + b)
    mov [ebp-12], eax

    Prompt  ans
    PutInt  [ebp-12]
    PutEoL

    mov esp, ebp
    pop ebp     # unwinding stack-frame
    ret

.global _entry

.end

推荐答案

也许您对此感到疑惑:

push    ebp
mov ebp, esp
sub esp, 12

这些行被称为汇编功能序言.前2条指令保存前一个基本指针(ebp),并将EBP设置为指向堆栈上的该位置(在返回地址的正下方).这会将EBP设置为

These lines are known as the assembly function prologue. The first 2 instructions save the previous base pointer (ebp) and set EBP to point at that position on the stack (right below the return address). This sets up EBP as a frame pointer.

sub esp,12行为函数中的局部变量节省了空间.可用[ebp - 4]这样的寻址模式来寻址该空间.函数args的任何推入/弹出操作,或者call指令本身推入返回地址,或我们调用的函数的堆栈框架,都将在当前ESP的此保留空间以下进行.

The sub esp,12 line is saving space for local variables in the function. That space can be addressed with addressing modes like [ebp - 4]. Any push/pop of function args, or the call instruction itself pushing a return address, or stack frames for functions we call, will happen below this reserved space, at the current ESP.

最后,您有:

mov esp, ebp         ; restore ESP
pop ebp              ; restore caller's EBP
ret                  ; pop the return address into EIP

这是序言的反义词(即结语),因此可以恢复先前的上下文.有时称为撕毁"堆栈框架.

This is the inverse the prologue does (i.e. the epilogue), so the previous context can be restored. This is sometimes called "tearing down" the stack frame.

(EBP在所有标准x86呼叫约定中都是非易失性的,又称为呼叫保留:如果对其进行修改,则必须恢复呼叫者的值.)

(EBP is non-volatile aka call-preserved in all standard x86 calling conventions: if you modify it, you have to restore your caller's value.)

leave 指令完全执行这两个指令,并由一些编译器可以节省代码大小. (enter 0,0非常慢且从未使用过( https://agner.org/optimize/); leave的效率与mov + pop差不多.)

The leave instruction does exactly what these two instructions do, and is used by some compilers to save code size. (enter 0,0 is very slow and never used (https://agner.org/optimize/); leave is about as efficient as mov + pop.)

请注意,使用EBP作为帧指针是可选,并且编译器不会针对优化代码中的大多数功能执行此操作.相反,他们保存了单独的元数据以允许堆栈展开/回溯.

Note that using EBP as a frame pointer is optional, and compilers don't do it for most functions in optimized code. Instead they save separate metadata to allow stack unwinding / backtrace.

这篇关于汇编中有关push ebp和pop ebp指令的说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆