Demystifying Memory in EVM (Part II)

Demystifying Memory in EVM (Part II)

Alright Let’s Continue from where we left ,

Previous One : Demystifying Memory in EVM (Part I)

Memory Initialization

When a contract is executed , the EVM initializes a free memory pointer to 0×80. This is done to provide some space for stack operations and other data that the contract might need during execution. This means the first 128 bytes of memory (from 0×00 to 0×7f ) are reserved and the free memory pointer points to 0×80

Mstore8

The mstore8 keyword utilizes exactly 1 byte or 8 bits to store a value , compared to the mstore which utilizes all 32 bytes or 256 bits to store value

Storing Strings in Memory

function test() external pure { 
    string memory str = "hello";
}

Lets Visualize how this would exist in the EVM Memory!

  • Initially the 0×40 slot would be storing 0×80 as the free memory slot, However after the string “hello” . now that the slot is occupied hence the next free slot is 0xc0, so any new data will be stored at 0xc0

  • In Solidity , the free memory pointer is a special pointer that points to the first free memory location in the contracts memory

Memory in Solidity is divided into 2 regions

  1. Reserved memory : This region is reserved for storing the contract’s code and permanent data

  2. Free Memory: This region is available for storing temporary data , such as local variable and functions call data

Another Example of Free memory Pointer

function storeArray() public pure returns (bytes32){
    bytes32 freeMemoryPointer;
    assembly{
       // Load the value from memory location 0x40
        freeMemoryPointer := mload(0x40); 
    }
    uint8[3] memory array1 = [1,2,3]
    uint8[3] memory array2 = [4,5,6]
    return freeMemoryPointer;
}

Visualizing the State of EVM Memory

  • Note : When you declare a new variable or array in a function Solidity allocates memory for it by incrementing the free memory pointer. The allocated memory is only valid for the duration of the function call and is released when the function returns

Changing the free memory pointer

contract Test{
function testing() external pure returns(uint data1,uint data2 ,uint data3)
    {
        assembly{
            mstore(0x40,0xa0) // Line 3
        }
        uint8[3] tempArray = [1,2,3];
        assembly{ // Line 7
            data1 := mload(0xa0)
            data2 := mload(add(0xa0,0x20)) // 0xa0 = 0x20 = 0xc0
            data3 := mload(add(0xa0,0x40)) // 0xa0 = 0x40 = 0xe0

        }
        return (data1,data2,data3);
    }
}
  • Alright let’s understand the above code , First of all in Line 3 we relocate our Free memory pointer to point at 0xa0 , because by default the 0×40 points at 0×80

  • In Line 7 we are performing manual retrieval of the array elements as you can see for data2 and data3 , we are explicitly accessing the slot 0xc0 and 0xe0 by adding 0×20 and 0×40

Visualizing the State of EVM Memory