Function 堆栈成形

Function 堆栈成形,function,assembly,stack,Function,Assembly,Stack,有一个堆栈配置,它是 Parameter #N ... ... Parameter 2 Parameter 1 Return Address Old %ebp Local Variable 1 Local Variable 2 I have no idea what `"Old %ebp"` for. 如果%ebp用于访问返回地址和参数,那么为什么%ebp不直接指向 返回地址而不是“旧%ebp” 它是供将来使用的吗 我的问题是 问题1。“旧%ebp”的用途是什么?它是什么

有一个堆栈配置,它是

Parameter #N
...
...
Parameter 2   
Parameter 1
Return Address
Old %ebp  
Local Variable 1   
Local Variable 2


I have no idea what `"Old %ebp"` for.
如果
%ebp
用于访问返回地址和参数,那么为什么
%ebp
不直接指向

返回地址而不是
“旧%ebp”

它是供将来使用的吗

我的问题是

  • 问题1。“旧%ebp”的用途是什么?它是什么
  • 问题2。为什么%ebp点旧%ebp不只是返回地址

ebp寄存器(基指针)通常用于处理堆栈帧(堆栈的不同“级别”)。虽然堆栈指针可以根据推送和弹出的内容进行更改,但在相同的堆栈级别上,基本指针保持不变

这样,您就可以获取
ebp
一侧的所有局部变量(例如,
mov ax,[ebp-8]
)和另一侧的所有传递参数(例如,
mov ax,[ebp+12]
),以及与
ebp
相关的任何其他位置,例如某些情况下的返回代码

将基指针的上一个内容推送到堆栈上的原因是,当您向上移动到上一个堆栈帧时,很容易恢复该值。您只需将该值弹出到
ebp
中,它就会被恢复,这意味着您可以访问局部变量并为下一级访问传递的参数

提供了它如何工作的图形概述,我通常认为这是非常宝贵的:

    +------------------+
+-> |   prev-prev EBP  |
|   +------------------+
|   | function param 2 |
|   +------------------+
|   | function param 1 |
|   +------------------+
|   |  return address  |
|   +------------------+
+---|   previous EBP   | <-- current EBP
    +------------------+
    |   local var 1    |
    +------------------+
它保存旧的
ebp
,并设置一个新的,指向调用代码推送的变量。堆栈指针的减法是为局部变量分配空间

如前所述,这意味着可以使用
[ebp+N]
获取通过的参数,并使用
[ebp-N]
获取局部变量

epilog代码为反向操作:

add  esp, 16h      ; forget about locals.
pop  ebp           ; restore previous value
ret                ; return to calling code.

在此之后,
ebp
现在设置为其先前的值。

在处理堆栈帧(堆栈的不同“级别”)时,通常使用
ebp
寄存器(基指针)。虽然堆栈指针可以根据推送和弹出的内容进行更改,但在相同的堆栈级别上,基本指针保持不变

这样,您就可以获取
ebp
一侧的所有局部变量(例如,
mov ax,[ebp-8]
)和另一侧的所有传递参数(例如,
mov ax,[ebp+12]
),以及与
ebp
相关的任何其他位置,例如某些情况下的返回代码

将基指针的上一个内容推送到堆栈上的原因是,当您向上移动到上一个堆栈帧时,很容易恢复该值。您只需将该值弹出到
ebp
中,它就会被恢复,这意味着您可以访问局部变量并为下一级访问传递的参数

提供了它如何工作的图形概述,我通常认为这是非常宝贵的:

    +------------------+
+-> |   prev-prev EBP  |
|   +------------------+
|   | function param 2 |
|   +------------------+
|   | function param 1 |
|   +------------------+
|   |  return address  |
|   +------------------+
+---|   previous EBP   | <-- current EBP
    +------------------+
    |   local var 1    |
    +------------------+
它保存旧的
ebp
,并设置一个新的,指向调用代码推送的变量。堆栈指针的减法是为局部变量分配空间

如前所述,这意味着可以使用
[ebp+N]
获取通过的参数,并使用
[ebp-N]
获取局部变量

epilog代码为反向操作:

add  esp, 16h      ; forget about locals.
pop  ebp           ; restore previous value
ret                ; return to calling code.

之后,
ebp
现在设置为其以前的值。

%ebp
是基指针,所有参数和局部变量都作为基指针的偏移量进行访问。当前ebp将指向具有旧%ebp的堆栈

例如
局部变量1存储在%ebp-4
参数1存储在%ebp+8

“Old%ebp”
是调用者函数的基指针,当调用者返回要还原的基指针旧调用者时

为了回答你的第二个问题,它可以这样做,但这是惯例。这其中的一部分是

   push %ebp ; save old ebp to stack, this will become old ebp
   mov  %esp, %ebp  ; moving current base pointer to epp

PS:我主要使用nasm语法,因此可能是

%ebp
是基指针,所有参数和局部变量都作为基指针的偏移量进行访问。当前ebp将指向具有旧%ebp的堆栈

例如
局部变量1存储在%ebp-4
参数1存储在%ebp+8

“Old%ebp”
是调用者函数的基指针,当调用者返回要还原的基指针旧调用者时

为了回答你的第二个问题,它可以这样做,但这是惯例。这其中的一部分是

   push %ebp ; save old ebp to stack, this will become old ebp
   mov  %esp, %ebp  ; moving current base pointer to epp
PS:我主要使用nasm语法,所以可能