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 | 從過程調用中返回 |