为什么我们在大会的被叫方中"PUSH EBP"和"MOV EBP, ESP"?



为什么我们push ebp作为程序集函数的被调用方中的第一个动作?

我知道然后我们使用mov edi, [ebp+8]来获取传入的变量,但我们esp已经指向 Caller 函数的返回地址。我们可以使用mov edi, [esp+4]轻松访问传入的变量,或者如果我们推送了被调用方寄存器,则mov edi, [esp+16] .

那么,为什么在cpu(ebp)中具有额外的寄存器,您以后必须在功能中进行管理?

push ebp
mov ebp, esp
...
mov esp, ebp
pop ebp

它在被调用方内建立一个新的堆栈帧,同时保留调用方的堆栈帧。堆栈帧允许使用相对于函数中任何位置的EBP的固定偏移量一致地访问传递的参数和局部变量,而ESP可以在函数运行时根据需要自由地继续修改。 ESP是一个移动目标,因此使用相对于ESP的动态偏移量访问参数和变量可能很棘手,如果不是不可能的话,具体取决于函数如何使用堆栈。 创建堆栈帧通常更安全,代价是使用几个字节的堆栈空间来保留指向调用方堆栈帧的指针。

Remy 给出的答案是完美的,但是这里有一个小补充,你也可能在之后看到的东西

mov ebp, esp

很有可能看到这样的指令:

sub esp, 20h   ; creating space for local variables with size 20h
sub esp, CCh   ; creating space for local variables with size CCh

有时与 AND 调用一起(如和 esp,0FFFFFFF0h)。这也是处理堆栈的一部分,这样做是为了让堆栈可以对齐并可被 16 整除。当然,所有这些都取决于使用的调用约定(cdecl,fastcall,stdcall等)。

最新更新