Из-за того, как структурирован стек вызовов при использовании объявления C .
Сначала вызывающий абонент push
4-байтовый y
, затем 4-байтовый xp
(этот порядок важен, поэтому C может поддерживать Variadic Functions ), тогда call
для вашей функции будет неявно push
адрес возврата, который также является 4-байтовым (это 32-битная программа).
Первое, что делает ваша функция, это push
состояние ebp
, которое необходимо будет восстановить позже, чтобы вызывающий мог продолжить работу должным образом, а затем скопировать текущее состояние esp
(указатель стека) на ebp
.В сумме:
push %ebp
movl %esp, %ebp
Это также известно как пролог функции .
Когда все это сделано, вы наконец готовы фактически выполнить код, который вы написали, вна этом этапе стек выглядит примерно так:
%ebp- ? = address of your local variables (which in this example you don't have)
%ebp+ 0 = address of the saved state of previous ebp
%ebp+ 4 = ret address
%ebp+ 8 = address where is stored the value of xp
%ebp+12 = address where is stored the value of y
%ebp+16 = out of bonds, this memory space belongs to the caller
Когда ваша функция будет выполнена, она обернет ее, установив esp
обратно на ebp
, затем pop
оригинал ebp
и ret
.
movl %ebp, %esp
pop %ebp
ret
ret
- это, по сути, ярлык для pop
указателя из стека и jmp
к нему.
Редактировать: Исправлен порядок параметров для сборки AT & T