This file contains an assembler from EVM opcodes to byte strings.
Note that due to the design of EVM, which depends on the binary representation of a smart contract, it is not the case that disassembling and then reassembling the same contract will yield the same sequence of bytes.
As a simple counterexample, consider the contract 0x60.
Disassembling and then reassembling this contract will yield 0x6000.
As such, assembly is not considered part of the semantics of EVM, but is provided merely as a sample implementation to ease readability and make it easier to write inputs to the KEVM semantics.
module EVM-ASSEMBLY
imports EVM
syntax OpCode ::= PUSH(Int, Int) [klabel(PUSHAsm)]
// --------------------------------------------------Cons-lists of opcodes form programs (using cons operator _;_).
Operator #revOps can be used to reverse a program.
syntax OpCodes ::= ".OpCodes" | OpCode ";" OpCodes
// --------------------------------------------------
syntax OpCodes ::= #revOps ( OpCodes ) [function]
| #revOpsAux ( OpCodes , OpCodes ) [function]
// --------------------------------------------------------------
rule #revOps(OPS) => #revOpsAux(OPS, .OpCodes)
rule #revOpsAux( .OpCodes , OPS' ) => OPS'
rule #revOpsAux( OP ; OPS , OPS' ) => #revOpsAux( OPS , OP ; OPS' ) syntax ByteArray ::= #asmOpCodes ( OpCodes ) [function]
// ------------------------------------------------------- syntax ByteArray ::= #asmOpCodes ( OpCodes, ByteArray ) [function, klabel(#asmOpCodesAux)]
// ------------------------------------------------------------------------------------------
rule #asmOpCodes( OPS ) => #asmOpCodes(#revOps(OPS), .ByteArray)
rule #asmOpCodes( PUSH(N, W) ; OCS, WS ) => #asmOpCodes(OCS, #asmOpCode(PUSH(N)) : (#padToWidth(N, #asByteStack(W)) ++ WS))
rule #asmOpCodes( OP ; OCS, WS ) => #asmOpCodes(OCS, #asmOpCode(OP) : WS) requires PUSH(_, _) :/=K OP
rule #asmOpCodes( .OpCodes, WS ) => WS syntax ByteArray ::= #asmOpCodes ( OpCodes, StringBuffer ) [function, klabel(#asmOpCodesAux)]
// ---------------------------------------------------------------------------------------------
rule #asmOpCodes( OPS ) => #asmOpCodes(OPS, .StringBuffer)
rule #asmOpCodes( PUSH(N, W) ; OCS, SB ) => #asmOpCodes(OCS, (SB +String chrChar(#asmOpCode(PUSH(N)))) +String Bytes2String(Int2Bytes(N, W, BE)))
rule #asmOpCodes( OP ; OCS, SB ) => #asmOpCodes(OCS, SB +String chrChar(#asmOpCode(OP))) [owise]
rule #asmOpCodes( .OpCodes, SB ) => String2Bytes(StringBuffer2String(SB)) syntax Int ::= #asmOpCode ( OpCode ) [function]
// -----------------------------------------------
rule #asmOpCode( STOP ) => 0
rule #asmOpCode( ADD ) => 1
rule #asmOpCode( MUL ) => 2
rule #asmOpCode( SUB ) => 3
rule #asmOpCode( DIV ) => 4
rule #asmOpCode( SDIV ) => 5
rule #asmOpCode( MOD ) => 6
rule #asmOpCode( SMOD ) => 7
rule #asmOpCode( ADDMOD ) => 8
rule #asmOpCode( MULMOD ) => 9
rule #asmOpCode( EXP ) => 10
rule #asmOpCode( SIGNEXTEND ) => 11
rule #asmOpCode( LT ) => 16
rule #asmOpCode( GT ) => 17
rule #asmOpCode( SLT ) => 18
rule #asmOpCode( SGT ) => 19
rule #asmOpCode( EQ ) => 20
rule #asmOpCode( ISZERO ) => 21
rule #asmOpCode( AND ) => 22
rule #asmOpCode( EVMOR ) => 23
rule #asmOpCode( XOR ) => 24
rule #asmOpCode( NOT ) => 25
rule #asmOpCode( BYTE ) => 26
rule #asmOpCode( SHL ) => 27
rule #asmOpCode( SHR ) => 28
rule #asmOpCode( SAR ) => 29
rule #asmOpCode( SHA3 ) => 32
rule #asmOpCode( ADDRESS ) => 48
rule #asmOpCode( BALANCE ) => 49
rule #asmOpCode( ORIGIN ) => 50
rule #asmOpCode( CALLER ) => 51
rule #asmOpCode( CALLVALUE ) => 52
rule #asmOpCode( CALLDATALOAD ) => 53
rule #asmOpCode( CALLDATASIZE ) => 54
rule #asmOpCode( CALLDATACOPY ) => 55
rule #asmOpCode( CODESIZE ) => 56
rule #asmOpCode( CODECOPY ) => 57
rule #asmOpCode( GASPRICE ) => 58
rule #asmOpCode( EXTCODESIZE ) => 59
rule #asmOpCode( EXTCODECOPY ) => 60
rule #asmOpCode( RETURNDATASIZE ) => 61
rule #asmOpCode( RETURNDATACOPY ) => 62
rule #asmOpCode( EXTCODEHASH ) => 63
rule #asmOpCode( BLOCKHASH ) => 64
rule #asmOpCode( COINBASE ) => 65
rule #asmOpCode( TIMESTAMP ) => 66
rule #asmOpCode( NUMBER ) => 67
rule #asmOpCode( DIFFICULTY ) => 68
rule #asmOpCode( GASLIMIT ) => 69
rule #asmOpCode( POP ) => 80
rule #asmOpCode( MLOAD ) => 81
rule #asmOpCode( MSTORE ) => 82
rule #asmOpCode( MSTORE8 ) => 83
rule #asmOpCode( SLOAD ) => 84
rule #asmOpCode( SSTORE ) => 85
rule #asmOpCode( JUMP ) => 86
rule #asmOpCode( JUMPI ) => 87
rule #asmOpCode( PC ) => 88
rule #asmOpCode( MSIZE ) => 89
rule #asmOpCode( GAS ) => 90
rule #asmOpCode( JUMPDEST ) => 91
rule #asmOpCode( PUSH(1) ) => 96
rule #asmOpCode( PUSH(2) ) => 97
rule #asmOpCode( PUSH(3) ) => 98
rule #asmOpCode( PUSH(4) ) => 99
rule #asmOpCode( PUSH(5) ) => 100
rule #asmOpCode( PUSH(6) ) => 101
rule #asmOpCode( PUSH(7) ) => 102
rule #asmOpCode( PUSH(8) ) => 103
rule #asmOpCode( PUSH(9) ) => 104
rule #asmOpCode( PUSH(10) ) => 105
rule #asmOpCode( PUSH(11) ) => 106
rule #asmOpCode( PUSH(12) ) => 107
rule #asmOpCode( PUSH(13) ) => 108
rule #asmOpCode( PUSH(14) ) => 109
rule #asmOpCode( PUSH(15) ) => 110
rule #asmOpCode( PUSH(16) ) => 111
rule #asmOpCode( PUSH(17) ) => 112
rule #asmOpCode( PUSH(18) ) => 113
rule #asmOpCode( PUSH(19) ) => 114
rule #asmOpCode( PUSH(20) ) => 115
rule #asmOpCode( PUSH(21) ) => 116
rule #asmOpCode( PUSH(22) ) => 117
rule #asmOpCode( PUSH(23) ) => 118
rule #asmOpCode( PUSH(24) ) => 119
rule #asmOpCode( PUSH(25) ) => 120
rule #asmOpCode( PUSH(26) ) => 121
rule #asmOpCode( PUSH(27) ) => 122
rule #asmOpCode( PUSH(28) ) => 123
rule #asmOpCode( PUSH(29) ) => 124
rule #asmOpCode( PUSH(30) ) => 125
rule #asmOpCode( PUSH(31) ) => 126
rule #asmOpCode( PUSH(32) ) => 127
rule #asmOpCode( DUP(1) ) => 128
rule #asmOpCode( DUP(2) ) => 129
rule #asmOpCode( DUP(3) ) => 130
rule #asmOpCode( DUP(4) ) => 131
rule #asmOpCode( DUP(5) ) => 132
rule #asmOpCode( DUP(6) ) => 133
rule #asmOpCode( DUP(7) ) => 134
rule #asmOpCode( DUP(8) ) => 135
rule #asmOpCode( DUP(9) ) => 136
rule #asmOpCode( DUP(10) ) => 137
rule #asmOpCode( DUP(11) ) => 138
rule #asmOpCode( DUP(12) ) => 139
rule #asmOpCode( DUP(13) ) => 140
rule #asmOpCode( DUP(14) ) => 141
rule #asmOpCode( DUP(15) ) => 142
rule #asmOpCode( DUP(16) ) => 143
rule #asmOpCode( SWAP(1) ) => 144
rule #asmOpCode( SWAP(2) ) => 145
rule #asmOpCode( SWAP(3) ) => 146
rule #asmOpCode( SWAP(4) ) => 147
rule #asmOpCode( SWAP(5) ) => 148
rule #asmOpCode( SWAP(6) ) => 149
rule #asmOpCode( SWAP(7) ) => 150
rule #asmOpCode( SWAP(8) ) => 151
rule #asmOpCode( SWAP(9) ) => 152
rule #asmOpCode( SWAP(10) ) => 153
rule #asmOpCode( SWAP(11) ) => 154
rule #asmOpCode( SWAP(12) ) => 155
rule #asmOpCode( SWAP(13) ) => 156
rule #asmOpCode( SWAP(14) ) => 157
rule #asmOpCode( SWAP(15) ) => 158
rule #asmOpCode( SWAP(16) ) => 159
rule #asmOpCode( LOG(0) ) => 160
rule #asmOpCode( LOG(1) ) => 161
rule #asmOpCode( LOG(2) ) => 162
rule #asmOpCode( LOG(3) ) => 163
rule #asmOpCode( LOG(4) ) => 164
rule #asmOpCode( CREATE ) => 240
rule #asmOpCode( CALL ) => 241
rule #asmOpCode( CALLCODE ) => 242
rule #asmOpCode( RETURN ) => 243
rule #asmOpCode( DELEGATECALL ) => 244
rule #asmOpCode( CREATE2 ) => 245
rule #asmOpCode( STATICCALL ) => 250
rule #asmOpCode( REVERT ) => 253
rule #asmOpCode( INVALID ) => 254
rule #asmOpCode( SELFDESTRUCT ) => 255
rule #asmOpCode( UNDEFINED(W) ) => W
endmodule