以太坊虛擬機

EVM 堆疊

堆疊是 EVM 的主要工作區——一疊後進先出(LIFO)的值,操作碼在運算時把值推上去、彈下來。如果說記憶體與儲存是 EVM 的便條紙和檔案櫃,那堆疊就是真正動筆算術的那一小塊桌面。每個做實際工作的操作都從這疊的頂端讀取輸入,再把結果寫回頂端。

兩個數字能精確定義它:堆疊最多容納 1,024 個項目,而每個項目都是 256 位元(32 位元組)的字。256 位元的寬度不尋常且刻意為之——它讓單一堆疊槽能完整裝下一個 Keccak-256 雜湊或一個以太坊地址而不必拆分,從而簡化密碼學程式碼。在已滿的 1,024 深堆疊上推入會引發堆疊溢位例外而回滾該呼叫;試圖從空堆疊彈出則是堆疊下溢,後果相同。

操作碼只能觸及堆疊有限的窗口。DUP1–DUP16 把頂端十六個項目之一複製到頂端,SWAP1–SWAP16 把頂端項目與接下來十六個之一互換。沒有任何操作碼能任意索引到更深處,這正是 Solidity 開發者會遇到那令人頭痛的「Stack too deep」(堆疊過深)編譯錯誤的原因:當函式同時周轉太多區域變數時,編譯器無法把它們全都保持在可觸及的 16 深窗口內,逼你重構(把變數打包成結構體、使用區塊作用域,或溢出到記憶體)。

由於堆疊快速、又沒有儲存所帶的 gas 懲罰,最佳化良好的合約會盡量把熱資料留在堆疊上。理解堆疊機制,對閱讀原始位元組碼、撰寫 Yul 或內聯組合語言,以及在最底層推理 gas 成本,都是不可或缺的。

開發者實際撞到的限制是 16 個項目的可觸及範圍(而非 1,024 的深度);你可以同時存活許多變數,但操作碼與它所需的值之間,至多只能隔約 16 個。