死磕以太坊原始碼分析之EVM指令集

mindcarver發表於2021-02-21

死磕以太坊原始碼分析之EVM指令集

配合以下程式碼進行閱讀:https://github.com/blockchainGuide/

寫文不易,給個小關注,有什麼問題可以指出,便於大家交流學習。

以下指令集持續更新,最新文章請參考上面

f4a720afd869d70c3d1d2149980ba0e9

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",

參考

https://mindcarver.cn

https://github.com/blockchainGuide

相關文章