0
# Assembly Operations
1
2
Convert EVM assembly language to bytecode with comprehensive support for individual instructions, multiple instruction sequences, and complete programs. Supports all Ethereum hard forks and provides both binary and hexadecimal output formats.
3
4
## Capabilities
5
6
### Single Instruction Assembly
7
8
Assemble a single EVM instruction from its textual representation, with support for operands and program counter positioning.
9
10
```python { .api }
11
def assemble_one(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK) -> Instruction:
12
"""
13
Assemble one EVM instruction from its textual representation.
14
15
Parameters:
16
- asmcode (str): Assembly code for one instruction (e.g., "PUSH1 0x40", "ADD")
17
- pc (int, optional): Program counter of the instruction. Default: 0
18
- fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")
19
20
Returns:
21
Instruction: An Instruction object with complete metadata
22
23
Raises:
24
AssembleError: If assembly fails due to invalid instruction or operand
25
"""
26
```
27
28
**Usage Examples:**
29
30
```python
31
from pyevmasm import assemble_one
32
33
# Simple instruction without operand
34
add_instr = assemble_one("ADD")
35
print(f"Opcode: 0x{add_instr.opcode:02x}") # 0x01
36
37
# Instruction with operand
38
push_instr = assemble_one("PUSH1 0x40")
39
print(f"Operand: 0x{push_instr.operand:x}") # 0x40
40
print(f"Bytes: {push_instr.bytes.hex()}") # 6040
41
42
# With program counter
43
jump_instr = assemble_one("JUMPI", pc=100)
44
print(f"PC: {jump_instr.pc}") # 100
45
```
46
47
### Multiple Instruction Assembly
48
49
Assemble a sequence of EVM instructions from multiline assembly code, returning a generator of Instruction objects.
50
51
```python { .api }
52
def assemble_all(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK):
53
"""
54
Assemble a sequence of textual representation of EVM instructions.
55
56
Parameters:
57
- asmcode (str): Assembly code for any number of instructions, separated by newlines
58
- pc (int, optional): Program counter of the first instruction. Default: 0
59
- fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")
60
61
Returns:
62
Generator[Instruction]: A generator of Instruction objects
63
64
Raises:
65
AssembleError: If assembly fails for any instruction
66
"""
67
```
68
69
**Usage Examples:**
70
71
```python
72
from pyevmasm import assemble_all
73
74
# Assemble multiple instructions
75
assembly_code = '''
76
PUSH1 0x80
77
PUSH1 0x40
78
MSTORE
79
PUSH1 0x4
80
CALLDATASIZE
81
LT
82
'''
83
84
instructions = list(assemble_all(assembly_code))
85
for instr in instructions:
86
print(f"{instr.pc:08x}: {instr}")
87
88
# With custom starting PC
89
instructions = list(assemble_all(assembly_code, pc=0x1000))
90
print(f"First instruction PC: 0x{instructions[0].pc:x}") # 0x1000
91
```
92
93
### Binary Assembly
94
95
Assemble EVM assembly code directly to binary bytecode format.
96
97
```python { .api }
98
def assemble(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK) -> bytes:
99
"""
100
Assemble an EVM program to binary bytecode.
101
102
Parameters:
103
- asmcode (str): An EVM assembler program
104
- pc (int, optional): Program counter of the first instruction. Default: 0
105
- fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")
106
107
Returns:
108
bytes: The binary representation of the bytecode
109
110
Raises:
111
AssembleError: If assembly fails
112
"""
113
```
114
115
### Hexadecimal Assembly
116
117
Assemble EVM assembly code to hexadecimal string representation, the most common format for EVM bytecode.
118
119
```python { .api }
120
def assemble_hex(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK) -> str:
121
"""
122
Assemble an EVM program to hexadecimal bytecode.
123
124
Parameters:
125
- asmcode (str): An EVM assembler program
126
- pc (int, optional): Program counter of the first instruction. Default: 0
127
- fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")
128
129
Returns:
130
str: The hex representation of the bytecode (prefixed with "0x")
131
132
Raises:
133
AssembleError: If assembly fails
134
"""
135
```
136
137
**Usage Examples:**
138
139
```python
140
from pyevmasm import assemble, assemble_hex
141
142
assembly_code = '''
143
PUSH1 0x60
144
PUSH1 0x40
145
MSTORE
146
PUSH1 0x2
147
PUSH2 0x100
148
'''
149
150
# Get binary bytecode
151
binary_code = assemble(assembly_code)
152
print(f"Binary length: {len(binary_code)} bytes")
153
154
# Get hex bytecode (most common)
155
hex_code = assemble_hex(assembly_code)
156
print(f"Hex: {hex_code}") # "0x606040526002610100"
157
158
# Can also assemble from instruction list
159
from pyevmasm import assemble_all
160
instructions = list(assemble_all(assembly_code))
161
hex_from_list = assemble_hex(instructions)
162
print(f"Same result: {hex_code == hex_from_list}") # True
163
```
164
165
## Assembly Syntax
166
167
PyEVMAsm supports standard EVM assembly syntax:
168
169
- **Instructions**: Standard EVM mnemonics (ADD, SUB, PUSH1, etc.)
170
- **Operands**: Hexadecimal values with 0x prefix (PUSH1 0x40)
171
- **Line separation**: Newlines separate instructions
172
- **Comments**: Not supported in assembly input
173
- **Case sensitivity**: Mnemonics are case-insensitive but conventionally uppercase
174
175
## Fork-Specific Assembly
176
177
Different Ethereum forks support different instruction sets. PyEVMAsm handles this automatically:
178
179
```python
180
from pyevmasm import assemble_hex
181
182
# This works in byzantium and later
183
code = assemble_hex("RETURNDATASIZE", fork="byzantium")
184
185
# This would fail in earlier forks
186
try:
187
code = assemble_hex("RETURNDATASIZE", fork="frontier")
188
except AssembleError:
189
print("RETURNDATASIZE not available in frontier fork")
190
191
# Constantinople introduced new shift operations
192
code = assemble_hex("SHL", fork="constantinople") # Works
193
```