簡介
調用棧最經常被用於存放子程式的
返回地址。在調用任何子程式時,主程式都必須暫存子程式運行完畢後應該返回到的地址。因此,如果被調用的子程式還要調用其他的子程式,其自身的返回地址就必須存入調用棧,在其自身運行完畢後再行取回。在
遞歸程式中,每一層次遞歸都必須在調用棧上增加一條地址,因此如果程式出現無限遞歸(或僅僅是過多的遞歸層次),調用棧就會產生
棧溢出。
功能
調用棧的主要功能是存放
返回地址。除此之外,調用棧還用於存放:
彙編語言
main: li $a0, 3 li $a1, 4 jal sumsq move $s0, $v0 j mainendsumsq: addi $sp, $sp, -4 # 在堆疊上分配空間 sw $ra, 0($sp) # 將sumsq的返回位址存入堆疊中 jal square move $t0, $v0 move $a0, $a1 jal square add $v0, $v0, $t0 lw $ra, 0($sp) # 從堆疊中取回sumsq的返回位址 addi $sp, $sp, 4 # 釋出堆疊上分配的空間 jr $rasquare: mult $a0, $a0 mflo $v0 jr $ramainend:
這裡,主程式(main)調用“sumsq”子程式並將
返回地址存入暫存器ra,但是“sumsq”子程式需要調用“square”子程式。為保證sumsq的返回地址不被重寫,這個地址被存儲在棧中。在square子程式返回後,sumsq再從棧中取回其自身的返回地址。
安全性
在較底層語言(如
彙編語言與
C語言中),程控訊息與數據可能一同被存入調用棧中,因此造成安全隱患,可能允許惡意程式通過
棧緩衝區溢出(stack buffer overflow)來獲取程式的控制權。