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
一侧的所有局部变量(例如,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语法,所以可能