死磕以太坊原始碼分析之EVM指令集
配合以下程式碼進行閱讀:https://github.com/blockchainGuide/
寫文不易,給個小關注,有什麼問題可以指出,便於大家交流學習。
以下指令集持續更新,最新文章請參考上面
EVM 指令集概念
EVM執行的是位元組碼。由於操作碼被限制在一個位元組以內,所以EVM指令集最多隻能容納256條指令。目前EVM已經定義了100
多條指令,還有100多條指令可供以後擴充套件。這100多條指令包括算術運算指令,比較操作指令,按位運算指令,密碼學計算指令,棧、memory、storage操作指令,跳轉指令,區塊、智慧合約相關指令等。
EVM指令集
算數運算指令集
0x0
STOP: "STOP",
ADD: "ADD", //加法運算
MUL: "MUL", //乘法運算
SUB: "SUB", //減法運算
DIV: "DIV", //無符號整除運算
SDIV: "SDIV", //有符號整除運算
MOD: "MOD", //無符號取模運算
SMOD: "SMOD", //有符號取模運算
EXP: "EXP", //指數運算
NOT: "NOT",
//從棧頂彈出兩個元素,進行比較,
//然後把結果(1表示true,0表示false)推入棧頂。
//其中LT和GT把彈出的元素解釋為無符號整數進行比較,
//SLT和SGT把彈出的元素解釋為有符號數進行比較,EQ不關心符號
LT: "LT", //無符號小於比較
GT: "GT", //無符號大於比較
SLT: "SLT", //有符號小於比較
SGT: "SGT", //有符號大於比較
EQ: "EQ", // 等於比較
//SZERO指令從棧頂彈出一個元素,判斷它是否為0,如果是,則把1推入棧頂,否則把0推入棧頂
ISZERO: "ISZERO", //布林取反
//SIGNEXTEND指令從棧頂依次彈出k和x,並
//把x解釋為k+1(0 <= k <= 31)位元組有符號整數,然
//後把x符號擴充套件至32位元組。比如x是二進位制10000000,k是0,
//則符號擴充套件之後,結果為二進位制1111…10000000(共249個1)
SIGNEXTEND: "SIGNEXTEND" //符號位擴充套件
位運算指令集
0x10
//AND、OR、XOR指令從棧頂彈出兩個元素,進行按位運算,然後把結果推入棧頂
AND: "AND",
OR: "OR",
XOR: "XOR",
//BYTE指令先後從棧頂彈出n和x,取x的第n個位元組並推入棧頂。
//由於EVM的字長是32個位元組,所以n在[0, 31]區間內才有意義,
//否則BYTE的運算結果就是0。另外,位元組是從左到右數的,因此第0個位元組佔據字的最高位8個位元
BYTE: "BYTE",
//這三條指令都是先後從棧頂彈出兩個數n和x,
//其中x是要進行位移操作頂數,n是位移位元數,然後把結果推入棧頂
SHL: "SHL",
//SHR和SAR的區別在於,前者執行邏輯右移(空缺補0),後者執行算術右移(空缺補符號位)
SHR: "SHR",
SAR: "SAR",
ADDMOD: "ADDMOD",
//MULMOD指令依次從棧頂彈出x、y、z三個數,
//先計算x和y的乘積(不受溢位限制),再計算乘積和z的模,最後把結果推入棧頂
//假定乘積不會溢位,那麼MULMOD(x, y, z)等價於x * y % z
MULMOD: "MULMOD",
加密指令集
0x20
SHA3: "SHA3"
關閉狀態指令集
0x30
ADDRESS: "ADDRESS",
BALANCE: "BALANCE",
ORIGIN: "ORIGIN",
CALLER: "CALLER",
CALLVALUE: "CALLVALUE",
CALLDATALOAD: "CALLDATALOAD",
CALLDATASIZE: "CALLDATASIZE",
CALLDATACOPY: "CALLDATACOPY",
CODESIZE: "CODESIZE",
CODECOPY: "CODECOPY",
GASPRICE: "GASPRICE",
EXTCODESIZE: "EXTCODESIZE",
EXTCODECOPY: "EXTCODECOPY",
RETURNDATASIZE: "RETURNDATASIZE",
RETURNDATACOPY: "RETURNDATACOPY",
EXTCODEHASH: "EXTCODEHASH",
塊操作指令集
0x40
BLOCKHASH: "BLOCKHASH",
COINBASE: "COINBASE",
TIMESTAMP: "TIMESTAMP",
NUMBER: "NUMBER",
DIFFICULTY: "DIFFICULTY",
GASLIMIT: "GASLIMIT",
CHAINID: "CHAINID",
SELFBALANCE: "SELFBALANCE"
儲存和執行指令集
0x50
POP: "POP", // 棧頂彈出元素
MLOAD: "MLOAD",
MSTORE: "MSTORE",
MSTORE8: "MSTORE8",
SLOAD: "SLOAD", //先取出棧頂元素x,然後在storage中取以x為鍵的值(storage[x])存入棧頂
SSTORE: "SSTORE", //儲存storage是一個鍵值儲存,可將256位字對映到256位字
JUMP: "JUMP",
JUMPI: "JUMPI",
PC: "PC",
MSIZE: "MSIZE",
GAS: "GAS",
JUMPDEST: "JUMPDEST"
Push指令集
0x60
// PUSH系列指令把緊跟在指令後面的N(1 ~ 32)位元組元素推入棧頂
PUSH1: "PUSH1",
...
PUSH32: "PUSH32",
//DUP系列指令複製從棧頂開始數的第N(1 ~ 16)個元素,並把複製後的元素推入棧頂
DUP1: "DUP1",
DUP2: "DUP2",
...
DUP16: "DUP16",
//SWAP系列指令把棧頂元素和從棧頂開始數的第N(1 ~ 16)+ 1 個元素進行交換。
SWAP1: "SWAP1",
...
SWAP16: "SWAP16",
LOG0: "LOG0",
...
LOG4: "LOG4",