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

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

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

寫文不易,給個小關(guān)注,有什么問題可以指出,便于大家交流學(xué)習(xí)。

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

f4a720afd869d70c3d1d2149980ba0e9

EVM 指令集概念

EVM執(zhí)行的是字節(jié)碼。由于操作碼被限制在一個字節(jié)以內(nèi),所以EVM指令集最多只能容納256條指令。目前EVM已經(jīng)定義了100多條指令,還有100多條指令可供以后擴展。這100多條指令包括算術(shù)運算指令,比較操作指令,按位運算指令,密碼學(xué)計算指令,棧、memory、storage操作指令,跳轉(zhuǎn)指令,區(qū)塊、智能合約相關(guān)指令等。

EVM指令集

算數(shù)運算指令集

0x0

    STOP:       "STOP",
    ADD:        "ADD", //加法運算
    MUL:        "MUL", //乘法運算
    SUB:        "SUB", //減法運算
    DIV:        "DIV", //無符號整除運算
    SDIV:       "SDIV", //有符號整除運算
    MOD:        "MOD", //無符號取模運算
    SMOD:       "SMOD", //有符號取模運算
    EXP:        "EXP",  //指數(shù)運算
    NOT:        "NOT",
    
    //從棧頂彈出兩個元素,進行比較,
    //然后把結(jié)果(1表示true,0表示false)推入棧頂。
    //其中LT和GT把彈出的元素解釋為無符號整數(shù)進行比較,
    //SLT和SGT把彈出的元素解釋為有符號數(shù)進行比較,EQ不關(guān)心符號
    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)字節(jié)有符號整數(shù),然
    //后把x符號擴展至32字節(jié)。比如x是二進制10000000,k是0,
    //則符號擴展之后,結(jié)果為二進制1111…10000000(共249個1)
    SIGNEXTEND: "SIGNEXTEND" //符號位擴展

位運算指令集

0x10

    //AND、OR、XOR指令從棧頂彈出兩個元素,進行按位運算,然后把結(jié)果推入棧頂
    AND:    "AND",
    OR:     "OR",
    XOR:    "XOR",
    
    //BYTE指令先后從棧頂彈出n和x,取x的第n個字節(jié)并推入棧頂。
    //由于EVM的字長是32個字節(jié),所以n在[0, 31]區(qū)間內(nèi)才有意義,
    //否則BYTE的運算結(jié)果就是0。另外,字節(jié)是從左到右數(shù)的,因此第0個字節(jié)占據(jù)字的最高位8個比特
    BYTE:   "BYTE", 
    
    //這三條指令都是先后從棧頂彈出兩個數(shù)n和x,
    //其中x是要進行位移操作頂數(shù),n是位移比特數(shù),然后把結(jié)果推入棧頂
    SHL:    "SHL",
    //SHR和SAR的區(qū)別在于,前者執(zhí)行邏輯右移(空缺補0),后者執(zhí)行算術(shù)右移(空缺補符號位)
    SHR:    "SHR",
    SAR:    "SAR",
    
    ADDMOD: "ADDMOD",
    
    //MULMOD指令依次從棧頂彈出x、y、z三個數(shù),
    //先計算x和y的乘積(不受溢出限制),再計算乘積和z的模,最后把結(jié)果推入棧頂
    //假定乘積不會溢出,那么MULMOD(x, y, z)等價于x * y % z
    MULMOD: "MULMOD",

加密指令集

0x20

SHA3: "SHA3"

關(guān)閉狀態(tài)指令集

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"

存儲和執(zhí)行指令集

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)字節(jié)元素推入棧頂
    PUSH1:  "PUSH1",
    ...
    PUSH32: "PUSH32",

    //DUP系列指令復(fù)制從棧頂開始數(shù)的第N(1 ~ 16)個元素,并把復(fù)制后的元素推入棧頂
    DUP1:  "DUP1",
    DUP2:  "DUP2",
    ...
    DUP16: "DUP16",

    //SWAP系列指令把棧頂元素和從棧頂開始數(shù)的第N(1 ~ 16)+ 1 個元素進行交換。
    SWAP1:  "SWAP1",
    ...
    SWAP16: "SWAP16",
    
    LOG0:   "LOG0",
    ...
    LOG4:   "LOG4",

參考

https://mindcarver.cn

https://github.com/blockchainGuide

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容