CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyevmasm

Ethereum Virtual Machine (EVM) assembler and disassembler library for working with EVM bytecode and assembly instructions

Pending
Overview
Eval results
Files

instruction-analysis.mddocs/

Instruction Analysis

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.

Capabilities

Instruction Object

The core representation of EVM instructions with complete metadata and semantic analysis capabilities.

class Instruction:
    """
    Represents an EVM instruction with complete metadata and analysis capabilities.
    
    This class provides comprehensive information about EVM opcodes including
    basic properties, stack effects, memory/storage access patterns, and
    semantic classification for program analysis.
    """
    
    def __init__(self, opcode: int, name: str, operand_size: int, 
                 pops: int, pushes: int, fee: int, description: str,
                 operand: int = None, pc: int = 0):
        """
        Initialize an EVM instruction.

        Parameters:
        - opcode (int): The opcode value (0x00-0xFF)
        - name (str): Instruction name/mnemonic base (e.g., "PUSH", "DUP")
        - operand_size (int): Immediate operand size in bytes (0 for no operand)
        - pops (int): Number of items popped from the stack
        - pushes (int): Number of items pushed to the stack
        - fee (int): Basic gas fee for the instruction
        - description (str): Textual description of the instruction
        - operand (int, optional): Immediate operand value
        - pc (int, optional): Program counter of this instruction
        """

    def parse_operand(self, buf) -> None:
        """
        Parse an operand from a buffer.

        Parameters:
        - buf (iterator): A buffer/iterator of bytes

        Raises:
        ParseError: If not enough data for decoding operand
        """

Basic Properties

Core instruction identification and metadata properties.

class Instruction:
    @property
    def opcode(self) -> int:
        """The opcode as an integer (0x00-0xFF)."""
    
    @property
    def name(self) -> str:
        """The instruction name/mnemonic (long form, e.g., 'PUSH1', 'DUP2')."""
    
    @property
    def mnemonic(self) -> str:
        """Alias for name property."""
    
    @property
    def description(self) -> str:
        """Colloquial description of the instruction."""
    
    @property
    def semantics(self) -> str:
        """Canonical semantics (short name, e.g., 'PUSH', 'DUP')."""

Usage Examples:

from pyevmasm import disassemble_one

# Analyze a PUSH1 instruction
instr = disassemble_one(b'\x60\x40')  # PUSH1 0x40
print(f"Opcode: 0x{instr.opcode:02x}")      # 0x60
print(f"Name: {instr.name}")                # PUSH1
print(f"Semantics: {instr.semantics}")      # PUSH
print(f"Description: {instr.description}")  # Place 1 byte item on stack.

# Analyze a DUP instruction
instr = disassemble_one(b'\x81')  # DUP2
print(f"Name: {instr.name}")         # DUP2
print(f"Semantics: {instr.semantics}")  # DUP

Operand Analysis

Properties for analyzing instruction operands and immediate values.

class Instruction:
    @property
    def operand_size(self) -> int:
        """The immediate operand size in bytes."""
    
    @property
    def has_operand(self) -> bool:
        """True if the instruction uses an immediate operand."""
    
    @property
    def operand(self) -> int:
        """The immediate operand value (getter/setter)."""
    
    @operand.setter
    def operand(self, value: int) -> None:
        """Set the operand value with validation."""
    
    @property
    def size(self) -> int:
        """Size of the encoded instruction (1 + operand_size)."""
    
    @property
    def bytes(self) -> bytes:
        """Encoded instruction as bytes."""

Usage Examples:

from pyevmasm import assemble_one, disassemble_one

# Instructions with operands
push_instr = assemble_one("PUSH2 0x1234")
print(f"Has operand: {push_instr.has_operand}")    # True
print(f"Operand size: {push_instr.operand_size}")  # 2
print(f"Operand value: 0x{push_instr.operand:x}")  # 0x1234
print(f"Total size: {push_instr.size}")            # 3 (1 + 2)
print(f"Bytes: {push_instr.bytes.hex()}")          # 611234

# Instructions without operands
add_instr = assemble_one("ADD")
print(f"Has operand: {add_instr.has_operand}")     # False
print(f"Size: {add_instr.size}")                   # 1

Stack Analysis

Properties for analyzing stack effects and stack-based operations.

class Instruction:
    @property
    def pops(self) -> int:
        """Number of words popped from the stack."""
    
    @property
    def pushes(self) -> int:
        """Number of words pushed to the stack."""
    
    @property
    def uses_stack(self) -> bool:
        """True if the instruction reads/writes from/to the stack."""
    
    @property
    def reads_from_stack(self) -> bool:
        """True if the instruction reads from stack."""
    
    @property
    def writes_to_stack(self) -> bool:
        """True if the instruction writes to the stack."""

Usage Examples:

from pyevmasm import disassemble_one

# Stack effects analysis
add_instr = disassemble_one(b'\x01')  # ADD
print(f"Pops: {add_instr.pops}")         # 2 (pops two values)
print(f"Pushes: {add_instr.pushes}")     # 1 (pushes result)
print(f"Net stack: {add_instr.pushes - add_instr.pops}")  # -1

push_instr = disassemble_one(b'\x60\x01')  # PUSH1 0x01
print(f"Pops: {push_instr.pops}")        # 0
print(f"Pushes: {push_instr.pushes}")    # 1

# Stack usage detection
print(f"ADD uses stack: {add_instr.uses_stack}")      # True
print(f"ADD reads stack: {add_instr.reads_from_stack}")   # True
print(f"PUSH writes stack: {push_instr.writes_to_stack}") # True

Memory and Storage Analysis

Properties for analyzing memory and storage access patterns.

class Instruction:
    @property
    def writes_to_memory(self) -> bool:
        """True if the instruction writes to memory."""
    
    @property
    def reads_from_memory(self) -> bool:
        """True if the instruction reads from memory."""
    
    @property
    def writes_to_storage(self) -> bool:
        """True if the instruction writes to storage."""
    
    @property
    def reads_from_storage(self) -> bool:
        """True if the instruction reads from storage."""

Usage Examples:

from pyevmasm import disassemble_one

# Memory operations
mstore_instr = disassemble_one(b'\x52')  # MSTORE
print(f"Writes memory: {mstore_instr.writes_to_memory}")  # True

mload_instr = disassemble_one(b'\x51')   # MLOAD
print(f"Reads memory: {mload_instr.reads_from_memory}")   # True

# Storage operations
sstore_instr = disassemble_one(b'\x55')  # SSTORE
print(f"Writes storage: {sstore_instr.writes_to_storage}")  # True

sload_instr = disassemble_one(b'\x54')   # SLOAD
print(f"Reads storage: {sload_instr.reads_from_storage}")   # True

Control Flow Analysis

Properties for analyzing program control flow and execution patterns.

class Instruction:
    @property
    def is_terminator(self) -> bool:
        """True if the instruction is a basic block terminator."""
    
    @property
    def is_endtx(self) -> bool:
        """True if the instruction is a transaction terminator."""
    
    @property
    def is_starttx(self) -> bool:
        """True if the instruction is a transaction initiator."""
    
    @property
    def is_branch(self) -> bool:
        """True if the instruction is a jump."""

Usage Examples:

from pyevmasm import disassemble_one

# Control flow analysis
jump_instr = disassemble_one(b'\x56')    # JUMP
print(f"Is branch: {jump_instr.is_branch}")         # True
print(f"Is terminator: {jump_instr.is_terminator}") # True

jumpi_instr = disassemble_one(b'\x57')   # JUMPI
print(f"Is branch: {jumpi_instr.is_branch}")        # True

return_instr = disassemble_one(b'\xf3')  # RETURN
print(f"Is end tx: {return_instr.is_endtx}")        # True
print(f"Is terminator: {return_instr.is_terminator}")  # True

call_instr = disassemble_one(b'\xf1')    # CALL
print(f"Is start tx: {call_instr.is_starttx}")      # True

Semantic Classification

Properties for classifying instructions by their semantic purpose and EVM specification categories.

class Instruction:
    @property
    def group(self) -> str:
        """Instruction classification as per the Ethereum Yellow Paper."""
    
    @property
    def is_arithmetic(self) -> bool:
        """True if the instruction is an arithmetic operation."""
    
    @property
    def is_environmental(self) -> bool:
        """True if the instruction accesses environmental data."""
    
    @property
    def is_system(self) -> bool:
        """True if the instruction is a system operation."""
    
    @property
    def uses_block_info(self) -> bool:
        """True if the instruction accesses block information."""

Usage Examples:

from pyevmasm import disassemble_one

# Semantic classification
add_instr = disassemble_one(b'\x01')     # ADD
print(f"Group: {add_instr.group}")       # Stop and Arithmetic Operations
print(f"Is arithmetic: {add_instr.is_arithmetic}")  # True

caller_instr = disassemble_one(b'\x33')  # CALLER
print(f"Group: {caller_instr.group}")    # Environmental Information
print(f"Is environmental: {caller_instr.is_environmental}")  # True

timestamp_instr = disassemble_one(b'\x42')  # TIMESTAMP
print(f"Uses block info: {timestamp_instr.uses_block_info}")  # True

Gas Cost Analysis

Properties for analyzing gas costs and execution fees.

class Instruction:
    @property
    def fee(self) -> int:
        """The basic gas fee of the instruction."""

Usage Examples:

from pyevmasm import disassemble_one

# Gas cost analysis
add_instr = disassemble_one(b'\x01')     # ADD
print(f"Gas cost: {add_instr.fee}")     # 3

sstore_instr = disassemble_one(b'\x55')  # SSTORE (varies by fork)
print(f"Gas cost: {sstore_instr.fee}")  # 0 (complex gas calculation)

# Gas costs vary by fork
balance_istanbul = disassemble_one(b'\x31', fork="istanbul")
balance_frontier = disassemble_one(b'\x31', fork="frontier")
print(f"BALANCE gas (istanbul): {balance_istanbul.fee}")  # 700
print(f"BALANCE gas (frontier): {balance_frontier.fee}")  # 20

Program Counter Management

Properties for managing instruction positioning within programs.

class Instruction:
    @property
    def pc(self) -> int:
        """Program counter location of this instruction."""
    
    @pc.setter
    def pc(self, value: int) -> None:
        """Set the program counter location."""

Usage Examples:

from pyevmasm import assemble_one

# Program counter management
instr = assemble_one("PUSH1 0x40", pc=100)
print(f"PC: {instr.pc}")  # 100

# Modify PC
instr.pc = 200
print(f"New PC: {instr.pc}")  # 200

Install with Tessl CLI

npx tessl i tessl/pypi-pyevmasm

docs

assembly.md

disassembly.md

fork-management.md

index.md

instruction-analysis.md

tile.json