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
Reserved memory : This region is reserved for storing the contract’s code and permanent data
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