Laurent Knauss Software Engineer
fmp illustration

Free Memory Pointer (FMP) in the EVM

Introduction

In the Ethereum Virtual Machine (EVM), memory management is a crucial aspect of efficient smart contract execution. One key component of this system is the Free Memory Pointer (FMP), which determines where new dynamic allocations should be stored in memory. Understanding the FMP is essential for optimizing storage and gas usage in Solidity smart contracts.

What is the Free Memory Pointer (FMP)?

The Free Memory Pointer (FMP) is a special memory slot that holds the next available memory address. It ensures that new allocations do not overwrite existing data, allowing Solidity's dynamic structures (such as arrays, mappings, and structs) to expand safely.

  • The FMP is stored at a specific memory address.
  • It points to the next available, unallocated memory slot.
  • It gets updated whenever memory is allocated dynamically.

How the FMP Works

1. Initial State of the FMP

At the beginning of contract execution, the FMP is set to 0x80, as the first 256 bytes (0x00 to 0x7F) are reserved for the EVM memory layout (including scratch space and the FMP itself).

2. Allocating Memory

  • Reads the FMP - mload(0x40) - to get the current free memory address.
  • Writes data to that address.
  • Updates the FMP - mstore(0x40, new_address) - to point beyond the allocated space.

3. Example: Expanding a Dynamic Array

  • Reads the current FMP to find where to store the new element.
  • Writes the element in memory.
  • Moves the FMP forward to reserve space for future allocations.

Code Example

Here's a simple Solidity with some Assembly lines example demonstrating the FMP in action:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MemoryExample {
    function getFMP() external pure returns (uint256 fmp) {
        assembly {
            fmp := mload(0x40) // Load current Free Memory Pointer
        }
    }
    
    function allocateMemory() external pure returns (uint256 newFMP) {
        assembly {
            let fmp := mload(0x40) // Get current FMP
            mstore(fmp, 42)        // Store a value at FMP
            mstore(0x40, add(fmp, 32)) // Move FMP forward by 32 bytes
            newFMP := mload(0x40) // Return updated FMP
        }
    }
}

Why is the FMP Important?

  • Prevents memory overwrites: Ensures new allocations do not corrupt existing data.
  • Facilitates dynamic data structures: Used when expanding arrays or struct instances.
  • Optimizes gas efficiency: Proper memory management reduces unnecessary gas costs.

Conclusion

The Free Memory Pointer (FMP) is a critical component in Solidity's memory management. By tracking available memory space, it enables safe and efficient dynamic allocations. Understanding how to manipulate the FMP in inline assembly can lead to better contract optimization and lower gas costs.

🚀 Getting to know the FMP better gives you deeper control over smart contract memory handling, making your Solidity code more efficient and gas-optimized!

    Free Memory Pointer (FMP) in the EVM | Laurent