函數(shù)調(diào)用過程
- 當(dāng)主函數(shù)調(diào)用子函數(shù)的時(shí)候:
- 在主函數(shù)中,將子函數(shù)的參數(shù)按照一定調(diào)用約定(參考調(diào)用約定),一般是從右向左把參數(shù)push到棧中;
- 然后把下一條指令地址抄瑟,即返回地址(return address)push入棧(隱藏在call指令中);
- 然后跳轉(zhuǎn)到子函數(shù)地址處執(zhí)行: call 子函數(shù)枉疼;
- 此時(shí)子函數(shù)執(zhí)行:
-
push %rbp;
把當(dāng)前rbp的值保持在棧中皮假; -
mov %rsp, %rbp;
把rbp移到最新棧頂位置,即開啟子函數(shù)的新幀骂维; -
[可選]
sub $xxx, %esp;
在棧上分配XXX字節(jié)的臨時(shí)空間惹资。(即抬高棧頂,編譯器根據(jù)函數(shù)中的局部變量的總大小確定臨時(shí)空間的大小) -
[可選]
push XXX;
保存(push)一些寄存器的值;
- 子函數(shù)調(diào)用返回:
- 保持返回值:一般將函數(shù)函數(shù)值保持在eax寄存器中席舍;
- [可選] 恢復(fù)(pop)一些寄存器的值布轿;
-
mov %rbp,%rsp;
收回棧空間来颤,恢復(fù)主函數(shù)的棧頂汰扭; -
pop %rbp;
恢復(fù)主函數(shù)的棧底; -
ret;
從棧頂獲取之前保持的返回地址(return address)福铅,并跳轉(zhuǎn)到此位置執(zhí)行萝毛;
函數(shù)幀
image.png
棧的狀態(tài)變化
image.png