0
# Instruction Analysis
1
2
Rich instruction metadata and semantic analysis capabilities for EVM instruction inspection. The Instruction class provides comprehensive information about EVM opcodes including stack effects, memory/storage access patterns, control flow analysis, and gas costs.
3
4
## Capabilities
5
6
### Instruction Object
7
8
The core representation of EVM instructions with complete metadata and semantic analysis capabilities.
9
10
```python { .api }
11
class Instruction:
12
"""
13
Represents an EVM instruction with complete metadata and analysis capabilities.
14
15
This class provides comprehensive information about EVM opcodes including
16
basic properties, stack effects, memory/storage access patterns, and
17
semantic classification for program analysis.
18
"""
19
20
def __init__(self, opcode: int, name: str, operand_size: int,
21
pops: int, pushes: int, fee: int, description: str,
22
operand: int = None, pc: int = 0):
23
"""
24
Initialize an EVM instruction.
25
26
Parameters:
27
- opcode (int): The opcode value (0x00-0xFF)
28
- name (str): Instruction name/mnemonic base (e.g., "PUSH", "DUP")
29
- operand_size (int): Immediate operand size in bytes (0 for no operand)
30
- pops (int): Number of items popped from the stack
31
- pushes (int): Number of items pushed to the stack
32
- fee (int): Basic gas fee for the instruction
33
- description (str): Textual description of the instruction
34
- operand (int, optional): Immediate operand value
35
- pc (int, optional): Program counter of this instruction
36
"""
37
38
def parse_operand(self, buf) -> None:
39
"""
40
Parse an operand from a buffer.
41
42
Parameters:
43
- buf (iterator): A buffer/iterator of bytes
44
45
Raises:
46
ParseError: If not enough data for decoding operand
47
"""
48
```
49
50
### Basic Properties
51
52
Core instruction identification and metadata properties.
53
54
```python { .api }
55
class Instruction:
56
@property
57
def opcode(self) -> int:
58
"""The opcode as an integer (0x00-0xFF)."""
59
60
@property
61
def name(self) -> str:
62
"""The instruction name/mnemonic (long form, e.g., 'PUSH1', 'DUP2')."""
63
64
@property
65
def mnemonic(self) -> str:
66
"""Alias for name property."""
67
68
@property
69
def description(self) -> str:
70
"""Colloquial description of the instruction."""
71
72
@property
73
def semantics(self) -> str:
74
"""Canonical semantics (short name, e.g., 'PUSH', 'DUP')."""
75
```
76
77
**Usage Examples:**
78
79
```python
80
from pyevmasm import disassemble_one
81
82
# Analyze a PUSH1 instruction
83
instr = disassemble_one(b'\x60\x40') # PUSH1 0x40
84
print(f"Opcode: 0x{instr.opcode:02x}") # 0x60
85
print(f"Name: {instr.name}") # PUSH1
86
print(f"Semantics: {instr.semantics}") # PUSH
87
print(f"Description: {instr.description}") # Place 1 byte item on stack.
88
89
# Analyze a DUP instruction
90
instr = disassemble_one(b'\x81') # DUP2
91
print(f"Name: {instr.name}") # DUP2
92
print(f"Semantics: {instr.semantics}") # DUP
93
```
94
95
### Operand Analysis
96
97
Properties for analyzing instruction operands and immediate values.
98
99
```python { .api }
100
class Instruction:
101
@property
102
def operand_size(self) -> int:
103
"""The immediate operand size in bytes."""
104
105
@property
106
def has_operand(self) -> bool:
107
"""True if the instruction uses an immediate operand."""
108
109
@property
110
def operand(self) -> int:
111
"""The immediate operand value (getter/setter)."""
112
113
@operand.setter
114
def operand(self, value: int) -> None:
115
"""Set the operand value with validation."""
116
117
@property
118
def size(self) -> int:
119
"""Size of the encoded instruction (1 + operand_size)."""
120
121
@property
122
def bytes(self) -> bytes:
123
"""Encoded instruction as bytes."""
124
```
125
126
**Usage Examples:**
127
128
```python
129
from pyevmasm import assemble_one, disassemble_one
130
131
# Instructions with operands
132
push_instr = assemble_one("PUSH2 0x1234")
133
print(f"Has operand: {push_instr.has_operand}") # True
134
print(f"Operand size: {push_instr.operand_size}") # 2
135
print(f"Operand value: 0x{push_instr.operand:x}") # 0x1234
136
print(f"Total size: {push_instr.size}") # 3 (1 + 2)
137
print(f"Bytes: {push_instr.bytes.hex()}") # 611234
138
139
# Instructions without operands
140
add_instr = assemble_one("ADD")
141
print(f"Has operand: {add_instr.has_operand}") # False
142
print(f"Size: {add_instr.size}") # 1
143
```
144
145
### Stack Analysis
146
147
Properties for analyzing stack effects and stack-based operations.
148
149
```python { .api }
150
class Instruction:
151
@property
152
def pops(self) -> int:
153
"""Number of words popped from the stack."""
154
155
@property
156
def pushes(self) -> int:
157
"""Number of words pushed to the stack."""
158
159
@property
160
def uses_stack(self) -> bool:
161
"""True if the instruction reads/writes from/to the stack."""
162
163
@property
164
def reads_from_stack(self) -> bool:
165
"""True if the instruction reads from stack."""
166
167
@property
168
def writes_to_stack(self) -> bool:
169
"""True if the instruction writes to the stack."""
170
```
171
172
**Usage Examples:**
173
174
```python
175
from pyevmasm import disassemble_one
176
177
# Stack effects analysis
178
add_instr = disassemble_one(b'\x01') # ADD
179
print(f"Pops: {add_instr.pops}") # 2 (pops two values)
180
print(f"Pushes: {add_instr.pushes}") # 1 (pushes result)
181
print(f"Net stack: {add_instr.pushes - add_instr.pops}") # -1
182
183
push_instr = disassemble_one(b'\x60\x01') # PUSH1 0x01
184
print(f"Pops: {push_instr.pops}") # 0
185
print(f"Pushes: {push_instr.pushes}") # 1
186
187
# Stack usage detection
188
print(f"ADD uses stack: {add_instr.uses_stack}") # True
189
print(f"ADD reads stack: {add_instr.reads_from_stack}") # True
190
print(f"PUSH writes stack: {push_instr.writes_to_stack}") # True
191
```
192
193
### Memory and Storage Analysis
194
195
Properties for analyzing memory and storage access patterns.
196
197
```python { .api }
198
class Instruction:
199
@property
200
def writes_to_memory(self) -> bool:
201
"""True if the instruction writes to memory."""
202
203
@property
204
def reads_from_memory(self) -> bool:
205
"""True if the instruction reads from memory."""
206
207
@property
208
def writes_to_storage(self) -> bool:
209
"""True if the instruction writes to storage."""
210
211
@property
212
def reads_from_storage(self) -> bool:
213
"""True if the instruction reads from storage."""
214
```
215
216
**Usage Examples:**
217
218
```python
219
from pyevmasm import disassemble_one
220
221
# Memory operations
222
mstore_instr = disassemble_one(b'\x52') # MSTORE
223
print(f"Writes memory: {mstore_instr.writes_to_memory}") # True
224
225
mload_instr = disassemble_one(b'\x51') # MLOAD
226
print(f"Reads memory: {mload_instr.reads_from_memory}") # True
227
228
# Storage operations
229
sstore_instr = disassemble_one(b'\x55') # SSTORE
230
print(f"Writes storage: {sstore_instr.writes_to_storage}") # True
231
232
sload_instr = disassemble_one(b'\x54') # SLOAD
233
print(f"Reads storage: {sload_instr.reads_from_storage}") # True
234
```
235
236
### Control Flow Analysis
237
238
Properties for analyzing program control flow and execution patterns.
239
240
```python { .api }
241
class Instruction:
242
@property
243
def is_terminator(self) -> bool:
244
"""True if the instruction is a basic block terminator."""
245
246
@property
247
def is_endtx(self) -> bool:
248
"""True if the instruction is a transaction terminator."""
249
250
@property
251
def is_starttx(self) -> bool:
252
"""True if the instruction is a transaction initiator."""
253
254
@property
255
def is_branch(self) -> bool:
256
"""True if the instruction is a jump."""
257
```
258
259
**Usage Examples:**
260
261
```python
262
from pyevmasm import disassemble_one
263
264
# Control flow analysis
265
jump_instr = disassemble_one(b'\x56') # JUMP
266
print(f"Is branch: {jump_instr.is_branch}") # True
267
print(f"Is terminator: {jump_instr.is_terminator}") # True
268
269
jumpi_instr = disassemble_one(b'\x57') # JUMPI
270
print(f"Is branch: {jumpi_instr.is_branch}") # True
271
272
return_instr = disassemble_one(b'\xf3') # RETURN
273
print(f"Is end tx: {return_instr.is_endtx}") # True
274
print(f"Is terminator: {return_instr.is_terminator}") # True
275
276
call_instr = disassemble_one(b'\xf1') # CALL
277
print(f"Is start tx: {call_instr.is_starttx}") # True
278
```
279
280
### Semantic Classification
281
282
Properties for classifying instructions by their semantic purpose and EVM specification categories.
283
284
```python { .api }
285
class Instruction:
286
@property
287
def group(self) -> str:
288
"""Instruction classification as per the Ethereum Yellow Paper."""
289
290
@property
291
def is_arithmetic(self) -> bool:
292
"""True if the instruction is an arithmetic operation."""
293
294
@property
295
def is_environmental(self) -> bool:
296
"""True if the instruction accesses environmental data."""
297
298
@property
299
def is_system(self) -> bool:
300
"""True if the instruction is a system operation."""
301
302
@property
303
def uses_block_info(self) -> bool:
304
"""True if the instruction accesses block information."""
305
```
306
307
**Usage Examples:**
308
309
```python
310
from pyevmasm import disassemble_one
311
312
# Semantic classification
313
add_instr = disassemble_one(b'\x01') # ADD
314
print(f"Group: {add_instr.group}") # Stop and Arithmetic Operations
315
print(f"Is arithmetic: {add_instr.is_arithmetic}") # True
316
317
caller_instr = disassemble_one(b'\x33') # CALLER
318
print(f"Group: {caller_instr.group}") # Environmental Information
319
print(f"Is environmental: {caller_instr.is_environmental}") # True
320
321
timestamp_instr = disassemble_one(b'\x42') # TIMESTAMP
322
print(f"Uses block info: {timestamp_instr.uses_block_info}") # True
323
```
324
325
### Gas Cost Analysis
326
327
Properties for analyzing gas costs and execution fees.
328
329
```python { .api }
330
class Instruction:
331
@property
332
def fee(self) -> int:
333
"""The basic gas fee of the instruction."""
334
```
335
336
**Usage Examples:**
337
338
```python
339
from pyevmasm import disassemble_one
340
341
# Gas cost analysis
342
add_instr = disassemble_one(b'\x01') # ADD
343
print(f"Gas cost: {add_instr.fee}") # 3
344
345
sstore_instr = disassemble_one(b'\x55') # SSTORE (varies by fork)
346
print(f"Gas cost: {sstore_instr.fee}") # 0 (complex gas calculation)
347
348
# Gas costs vary by fork
349
balance_istanbul = disassemble_one(b'\x31', fork="istanbul")
350
balance_frontier = disassemble_one(b'\x31', fork="frontier")
351
print(f"BALANCE gas (istanbul): {balance_istanbul.fee}") # 700
352
print(f"BALANCE gas (frontier): {balance_frontier.fee}") # 20
353
```
354
355
### Program Counter Management
356
357
Properties for managing instruction positioning within programs.
358
359
```python { .api }
360
class Instruction:
361
@property
362
def pc(self) -> int:
363
"""Program counter location of this instruction."""
364
365
@pc.setter
366
def pc(self, value: int) -> None:
367
"""Set the program counter location."""
368
```
369
370
**Usage Examples:**
371
372
```python
373
from pyevmasm import assemble_one
374
375
# Program counter management
376
instr = assemble_one("PUSH1 0x40", pc=100)
377
print(f"PC: {instr.pc}") # 100
378
379
# Modify PC
380
instr.pc = 200
381
print(f"New PC: {instr.pc}") # 200
382
```