_function:
push ebp ;store the old base pointer
mov ebp, esp ;make the base pointer point to the current
;stack location – at the top of the stack is the
;old ebp, followed by the return address and then
;the parameters.
sub esp, x ;x is the size, in bytes, of all
;"automatic variables" in the function
堆栈顶部的是旧的 ebp,后跟返回地址 然后参数。
旧的ebp是因为push ebp
,
但为什么返回地址和参数呢?
更新
标准退出序列
mov esp, ebp ;reset the stack to "clean" away the local variables
pop ebp ;restore the original base pointer
ret ;return from the function
ret
实际上做了什么?我认为esp应该已经到达pop ebp
行的返回地址
答案 0 :(得分:4)
在x86标准调用约定中,在调用函数之前,首先将参数推送到堆栈。
call
op表示“将下一个地址推送到堆栈,然后跳转到函数”,因此返回地址也在堆栈上。
这意味着,在push ebp
之前,堆栈看起来像:
...
param2
param1
param0
return_address <- esp
致电push ebp
后,它变为
...
param2
param1
param0
return_address
ebp <- esp
最后,mov ebp, esp
将此esp
存储到ebp
中,因此您可以引用相对于ebp
的返回地址和所有输入参数,并将堆栈释放到本地使用
答案 1 :(得分:0)
这是ABI的全部内容。按照惯例,调用者创建一个包含参数等的stack frame
,然后调用该函数(在此过程中,返回地址也被压入堆栈)。被调用的函数将在堆栈上为局部变量分配额外的空间,并且可以通过一个公共指针和偏移量引用参数和局部变量。