X86下C语言函数使用栈帧来实现传入参数和处理局部变量的。
每个函数开始前都将执行
pushl %ebp
movl %esp,%ebp
结束时都将执行
leave
ret
以sum函数为例
int sum(int a,int b)
{
return a+b;
}
它的汇编代码
.text
.global sum
sum:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
addl 12(%ebp),%eax
leave
ret
然后是main函数
int main(void)
{
int a;
int b=12;
int c=24;
a=sum(b,c);
return 0;
}
汇编代码为
.text
.global main
main:
pushl %ebp
movl %esp,%ebp
subl $12,%esp
movl $12,-8(%ebp)
movl $24,-12(%ebp)
pushl -12(%ebp)
pushl -8(%ebp)
call sum
addl $8,%esp
movl %eax,-4(%ebp)
movl $0,%eax
leave
ret
首先,main函数在开始处执行pushl %ebp movl %esp,%ebp
然后subl $12,%esp movl $12,-8(%ebp) movl $24,-12(%ebp)
传入sum函数的参数 pushl -12(%ebp) pushl -8(%ebp)
执行call sum
程序流程调到sum函数处执行
pushl %ebp movl %esp,%ebp
leave ,leave等于movl %ebp,%esp popl %ebp
ret 从函数中返回,到addl $8,%esp这一指令。
addl $8,%esp
函数栈帧返回到main的状态。
以上就是一次调用函数的过程,我们可以看出函数调用是如何借助于栈帧完成函数调用的。
用到的指令
指令 | 描述 |
---|---|
call label | 过程调用 |
call *operand | 过程调用 |
leave | 为返回准备栈 |
ret | 从过程调用中返回 |