堆疊暫存器

堆疊暫存器是微处理器中，處理呼叫堆疊的暫存器。在以累加器為基礎的處理器中，堆疊暫存器可能是某個特定的暫存器。若是有多個通用暫存器的處理器架構，堆疊暫存器可能是某個依慣例保留的暫存器，像是IBM System/360、架構以及RISC架構，也有可能是用副程式呼叫或程式返回指令，硬編碼的暫存器，例如PDP-11、VAX和Intel x86架構。有些處理器（像）沒有專用的堆疊暫存器，而是用保留的硬體記憶體位置來處理此功能。

在1960年末期以前的處理器（例如PDP-8和）沒有可以支援递归呼叫的編譯器。其程序呼叫指令會將目前程式指標位置儲存在跳躍地址，接著將程式指標設定為下一個位置。此作法比維護堆疊簡單，因為每一個副程式只會有一個返回位址，但除非程式作大幅相關更動，此作法無法支援递归呼叫。

堆疊結構機器（Stack machine）可能會有二個或多個堆疊暫存器，其中有一個處理呼叫堆疊，其他暫存器則處理其他堆栈。

 x86的堆疊暫存器 
x86架構16位元的處理器裡，主堆疊暫存器是16位元的堆疊指標（Stack Pointer，SP）, 32位元的IA-32裡，擴展為32位元的擴展堆疊指標（Extended Stack Pointer, ESP），64位元的X86-64裡，擴展為64位元的暫存器堆疊指標（Register Stack Pointer，RSP）。堆疊區段暫存器（stack segment register，SS）會儲存目前執行程式呼叫堆疊的記憶體分段相關資訊。SP會指向目前堆疊的最頂端。預設情形，堆疊會以記憶體減少的方式成長，因此比較新的資料會放在較低的記憶體位置。PUSH指令可以將值存在堆疊裡，因此堆疊會增加一個資料，POP指令可以提取堆疊中的資訊，並且堆疊會減少一筆資料。

假設SS = 1000h，SP = 0xF820，這表示目前的堆疊頂是在實體地址0x1F820（這是因為Intel 8086的記憶體分區機制），接下來的二個機器碼是

PUSH AX
PUSH BX

 第一個指令會將AX（16位元暫存器）的值放在堆疊內，SP數值會減2。
 新的SP值是0xF81E。CPU會將AX的值複製到0x1F81E.
 執行PUSH BX時，會設定SP為0xF81C，將BX的值複製到0x1F81C。

上述就是PUSH運作的原理。一般來說，程式將暫存器的資料PUSH到堆疊是有其目的，例如呼叫會更改暫存器值的副程式。若要提取堆疊中的程式，可以用以下的機器碼

POP BX
POP AX

 POP BX將0x1F81C位置的字元（是BX原來的值）複製到BX，接著將SP加2，SP值是0xF81E。
 POP AX將0x1F81E位置的字元複製到AX，接著將SP加2，SP值是0xF820。

 堆疊機 
較簡單的處理器會將堆疊指標儲存在一般的硬體暫存器，用算術邏輯單元（ALU）來處理其數值。一般來說push和pop會翻譯為多個微指令，去增加或減少堆疊指標，處理記憶體的讀取和寫入。

較新的處理器會有專用的堆疊機（stack engine）以最佳化堆疊操作。Intel的Pentium M是第一個有堆疊機的x86處理器，其實現方式是將堆疊指標分為兩個暫存器：ESPO是32位元的暫存器，ESPd是8位元的偏移值，會依堆疊操作而更新其數值。PUSH、POP、CALL和RET微指令直接對ESPd運作。若If ESPd接近溢位，或是ESP暫存器被其他指令更新（而ESPd ≠ 0），此時會插入同步的微指令，用ALU更新ESPO，並且讓ESPd為0。在後續的Intel處理器中，此機制大致保留，不過將ESPO擴充到64位元。

AMD K8微處理器使用一種類似於Intel堆疊機的作法。在其推土機微架構中，不需要加入同步的微指令，但不清楚其堆疊機的內部設計。

 註解 

 參考資料 

Category:控制流程
Category:中央處理器
Category:數位寄存器