当我查看一些汇编代码时,我注意到函数具有以下结构:
My_Function:
; Function Prologue
push EBP
mov EBP, ESP
sub ESP, 0x28 ;40 Bytes local variable allocation
; Some code here
; Function epilogue
leave
ret
因此,如果我们假设My_Function
采用1个字节的参数,那么从堆栈帧中删除的位置。据我所知,函数的堆栈包含以下结构(从较低地址到较高地址):
LOW ADDRESS > | Local Variables |
| Old EBP Value |
| Return Address |
HIGH ADDRESS > | Arguments |
-------------------
| Previous Stack |
| Frame |
哪个汇编命令“删除”函数的参数?
据我所知leave
和ret
(所谓的函数结尾),修改值中的$esp
和$ebp
寄存器以指向前一个堆栈帧。但我不确定当函数结尾执行时$esp
是否恰好指向前一个堆栈帧的局部变量“start”,如您所见:
在执行功能结尾之前:
LOW ADDRESS > | Local Variables | < ESP
| Old EBP Value | < EBP
| Return Address |
| Arguments |
-------------------
| Local Variables |
| Old EBP Value |
| Return Address |
HIGH ADDRESS > | Arguments |
执行功能结尾后,有两个选项:
1)选项1:
LOW ADDRESS > | Local Variables | < ESP
| Old EBP Value | < EBP
| Return Address |
高地址&gt; |参数|
2)选项2:
| Arguments | < ESP
-------------------
LOW ADDRESS > | Local Variables |
| Old EBP Value | < EBP
| Return Address |
高地址&gt; |参数|
哪个选项是正确的,哪个命令的函数负责使esp
寄存器指向正确的地址?
答案 0 :(得分:-3)
函数的参数并不总是在栈上传递。 x86和x86-64的大多数ABI约定规定在寄存器中传递第一个参数,并且只有当它们中有太多传递时才会在堆栈中传递其余的参数。
除了x86-64 ABI:https://www.uclibc.org/docs/psABI-x86_64.pdf关于调用约定:
这样做的好处是内存访问比寄存器访问慢,所以只要有可能就必须避免它们。返回值也是如此 - 如果可能,它会在寄存器中返回。
如果堆栈上确实存在参数,以及本地自动变量,它们可以被解除分配&#34;只需恢复以前保存的RSP值即可。那不是leave
那么做的吗?