执行函数前(已经调用)(prologue):
将参数逆序压入堆栈(这样在使用ebp+偏移量来访问参数时,可以不考虑参数的数量,直接用%ebp+8(,%ebp+12...)等访问第1个至第N个参数)
pushl $3 # push the n parameter
pushl $2 # push the secondary parameter
pushl $1 # push the first parameter
call fun #
参数n
.
.
.
参数(3):
参数(2):
参数(1):
返回地址:
执行函数(body):
保存原来的ebp至堆栈中
pushl %ebp
.
参数3:
参数2:
参数1:
返回地址:
%ebp(原)
将现在的ebp赋值为esp
movl %esp,%ebp
参数3:
参数2:
参数1:
返回地址:
%ebp(原)
创建空间(下移esp指针)用于保存局部变量
subl $8,%esp
参数3:
参数2:
参数1:
返回地址:
%ebp(原)
|
|
返回(epilogue):
保存返回值至eax
movl -n(%ebp), %eax
丢弃创建的空间(将esp指针移至现ebp)
movl %ebp, %esp
参数3:
参数2:
参数1:
返回地址:
%ebp
|
|
弹出ebp的旧值装入现在ebp中
popl %ebp
参数3:
参数2:
参数1:
返回地址:
|
|
|
ret指令通过把返回地址从堆栈中弹出到程序计数器,从而从该函数返回
ret