BasicBlock:
在解释EVM是如何执行之前,先来解释一下BasicBlock(基本块)。一个基本块由一系列的指令构成,有一个入口和一个出口,入口就是第一个指令,出口就是最后一个指令。出口的类型有: 1. 条件跳转(JUMPI),2. 非条件跳转(JUMP),3. 结束指令(RETURN,REVERT)4.什么都没有,直接fall to下一个block
1. 条件跳转(JUMPI):
EVM中条件跳转的指令是JUMPI,它会从stack中读取2个元素,分别代表跳转的条件和pc(programmer counter)。下面是一个JUMPI的跳转例子:
Block1: JUMPDEST CALLVALUE ISZERO PUSH2 0x0100 JUMPI
Block2: PUSH1 0x00 DUP1 REVERT
Block1由5个指令构成(PUSH2 0x0100是一个), JUMPDEST表明这个Block是一个跳转的起始位置,CALLVALUE代表从transaction中获得的值,比如用户发送的ether额度,就可以用该指令获得。ISZERO判断CALLVALUE获得的值是否为0, PUSH指令向stack中放入了一个值。 最后执行到JUMPI,它从条件中读取了两个值: 1.ISZERO(CALLVALUE) 2. 0x0100. 如果满足1,则跳转到0x0100指向的block, 否则继续执行下一个BasicBlock(Block2) (PS: 如果满足条件跳转之后,执行完跳转的Block会继续往下执行Block2,执行的方式是深度优先遍历的方式)
2. 非条件跳转(JUMP):
EVM中的非条件跳转由JUMP指令触发, 每次执行到JUMP指令时,都会从stack读出1个值,表示要跳转的pc。和JUMPI指令类似,执行完跳转块后,也会继续向下执行,执行方式是深度优先遍历
3. Fall to:
EVM的某些基本块没有跳转指令也没有结束指令,对于这些指令,执行完最后一个指令后会继续执行下一个指令。当然对于条件跳转来说,也会有fall to的情况。如在条件跳转中举的例子,在执行完Block1之后,会继续执行Block2。或者Block1的JUMPI跳转条件不满足,也会继续执行Block2.
在下一篇文章中,我会用一个具体的smart contract以及对应的指令来具体解释EVM bytecode的文件结构以及bytecode如何执行。