呼叫堆疊

呼叫堆疊（-{zh-cn:，港台称“呼叫堆叠”;zh-hk:，大陸稱「調用堆棧」;zh-tw:，中國稱「調用堆棧」}-）别称有：执行栈（execution stack）、控制栈（control stack）、运行时栈（run-time stack）与机器栈（machine stack），是電腦科學中存儲有關正在執行的子程式的訊息的堆疊。英文有時直接简称“栈”（the stack），但堆疊中不一定僅存儲子程式訊息。幾乎所有電腦程式都依賴於呼叫堆疊，而高階語言一般將呼叫堆疊的細節隱藏至後台。

呼叫堆疊最經常被用於存放子程式的返回位址。在呼叫任何子程式時，主程式都必須暫存子程式執行完畢後應該返回到的位址。因此，如果被呼叫的子程式還要呼叫其他的子程式，其自身的返回位址就必須存入呼叫堆疊，在其自身執行完畢後再行取回。在遞迴程式中，每一層次遞迴都必須在呼叫堆疊上增加一條位址，因此如果程式出現無限遞迴（或僅僅是過多的遞迴層次），呼叫堆疊就會產生堆疊溢位。

功能
呼叫堆疊的主要功能是存放返回位址。除此之外，呼叫堆疊還用於存放：
 本地變數：子程式的變數可以存入呼叫堆疊，這樣可以達到不同子程式間變數分離開的作用。
 參數傳遞：如果暫存器不足以容納子程式的參數，可以在呼叫堆疊上存入參數。
 環境傳遞：有些語言（如Pascal與Ada）支援「多層子程式」，即子程式中可以利用主程式的本地變數。這些變數可以通過呼叫堆疊傳入子程式。

實例

組合語言
以下MIPS組合語言程式計算，並將結果存至暫存器s0。
main:
    li      $a0, 3
    li      $a1, 4
    jal     sumsq
    move    $s0, $v0
    j       mainend
sumsq:
    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      $ra
square:
    mult    $a0, $a0
    mflo    $v0
    jr      $ra
mainend:
這裡，主程式（main）呼叫「sumsq」子程式並將返回位址存入暫存器ra，但是「sumsq」子程式需要呼叫「square」子程式。為保證sumsq的返回位址不被重寫，這個位址被存儲在堆疊中。在square子程式返回後，sumsq再從堆疊中取回其自身的返回位址。

安全性
在較底層語言（如組合語言與C語言中），程式控制訊息與資料可能一同被存入呼叫堆疊中，因此造成安全隱患，可能允許惡意程式通過栈缓冲区溢出（stack buffer overflow）來獲取程式的控制權。

參見
 記憶體管理
 调用约定
 堆疊溢位

计算机编程