複製鏈接
請複製以下鏈接發送給好友

調用棧

鎖定
調用棧(英語:Call stack,英文直接簡稱為“棧”(the stack))別稱有:執行棧(execution stack)、控制棧(control stack)、運行時棧(run-time stack)與機器棧(machine stack),是計算機科學中存儲有關正在運行的子程序的消息的。有時僅稱“棧”,但棧中不一定僅存儲子程序消息。幾乎所有計算機程序都依賴於調用棧,然而高級語言一般將調用棧的細節隱藏至後台。
中文名
調用棧
外文名
Call stack
目    的
存放子程序的返回地址
領    域
計算機

調用棧簡介

調用棧最經常被用於存放子程序的返回地址。在調用任何子程序時,主程序都必須暫存子程序運行完畢後應該返回到的地址。因此,如果被調用的子程序還要調用其他的子程序,其自身的返回地址就必須存入調用棧,在其自身運行完畢後再行取回。在遞歸程序中,每一層次遞歸都必須在調用棧上增加一條地址,因此如果程序出現無限遞歸(或僅僅是過多的遞歸層次),調用棧就會產生棧溢出 [1] 

調用棧功能

調用棧的主要功能是存放返回地址。除此之外,調用棧還用於存放:
  • 本地變量:子程序的變量可以存入調用棧,這樣可以達到不同子程序間變量分離開的作用。
  • 參數傳遞:如果寄存器不足以容納子程序的參數,可以在調用棧上存入參數。
  • 環境傳遞:有些語言(如PascalAda)支持“多層子程序”,即子程序中可以利用主程序的本地變量。這些變量可以通過調用棧傳入子程序。 [1] 

調用棧彙編語言

以下MIPS彙編語言程序計算
,並將結果存至寄存器s0。
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再從棧中取回其自身的返回地址。 [2] 

調用棧安全性

在較底層語言(如彙編語言C語言中),程控消息與數據可能一同被存入調用棧中,因此造成安全隱患,可能允許惡意程序通過棧緩衝區溢出(stack buffer overflow)來獲取程序的控制權。 [2] 
參考資料
  • 1.    戚曉芳, 周曉宇, 徐曉晶,等. 一種組合式基於調用棧的程序切片方法[J]. 東南大學學報(自然科學版), 2011, 41(6):1171-1176.
  • 2.    周宇. 基於調用棧完整性的緩衝區溢出檢測方法[J]. 計算機安全, 2010(3):16-19.