В стандартном соглашении о вызовах 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
, и освободить стек для локального использования.