DEV Community

ASHDEEP SINGH
ASHDEEP SINGH

Posted on

Intro to EVM IV

In this week we ended our tour de EVM and here's what all I learnt.

Memory management
Even though the name's memory , Memory is equivalent to the heap in other languages but there is no garbage collector.
Now , we'll explore it using an example to store a string.

first we have a scratch space , Scratch space in the Ethereum Virtual Machine (EVM) is a temporary memory area, 256 bytes in size, used for intermediate calculations during execution. It resets after each instruction and is cheaper to use than persistent memory or storage.

Then , we have home to FREE MEMORY POINTER, that is , the address where our thing will be stored next.

and then finally we have space where we store our data.

And to make things even more clear , we have reserved space for dynamic arrays.

here's how to understand it:
0x00 - scratch space
0x20 - scratch space
0x40 - stores next free address location
0x60 - Reserved for dynamic arrays
0x80 - where we actually store data

MStore and MLoad
Just like malloc of C , we can ourselves we can manually store some information in a particular address.
Here's how we do it :
mstore(0x00, valueToStore)

and as you might have guessed , we use Mload to retrieve our data.
Value := mload(0xa0)

So you might be thinking , we can just use any space and fill it to optimise . Well you cant ,reason being we have some reserved spaces for various other works. Have a look at it:
Hashing operations : 0x00 - 0x3f
Memory management : 0x40 - 0x5f
Zero Slot Usage : 0x60 - 0x7f

Also take a look at what happens behind the scenes to get a better understanding.

Memory Initialization:
When a contract is executed, the EVM initializes a free memory pointer to 0x80 (128 in decimal). 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 0x00 to 0x7F) are reserved, and the free memory pointer initially points to 0x80.
Loading the Free Memory Pointer:
In the assembly block, the command mload(0x40) loads the value stored at memory location 0x40. This location holds the address of the first free byte of memory. Since the EVM initializes this pointer to 0x80, mload(0x40) returns 0x80.
Memory Layout:
EVM memory is byte-addressed, meaning each address corresponds to one byte. However, memory operations like mload and mstore work with 32-byte (256-bit) words. So, when you read or write to memory, you deal with 32-byte chunks.
Interpreting the Result:
The value 0x0000000000000000000000000000000000000000000000000000000000000080 you received is a 32-byte word where the last byte (0x80) indicates the starting point of the free memory, and the preceding bytes are padded with zeros.

Instruction Set
We have a few instruction sets too that enable us to understand (& if needed , dive deeper into the knitty gritty of) EVM and bytecodes

Stack instructions
Stack instructions involve manipulating the position of values on the stack.
pushN value: pushes a value to the top of the stack where N is the byte size of the value.

pop: pops a value from the top of the stack.

swapN: swaps the value from the top of the stack with a value at stack index N.

dupN: duplicates a value from the stack at index N and pushes it to the stack.

Arithmetic Instructions
Arithmetic instructions pop two or more values from the stack, performs an arithmetic operation, and pushes the result.
add: pushes the result of addition of two values.

sub: pushes the result of subtraction of two values.

mul / smul: pushes the result of multiplication of two values.

div / sdiv: pushes the result of the division of two values.

mod: pushes the result of the modulus of two values.

exp: pushes the result of exponentiation of two values. addmod / mulmod combines add with mod and mul with mod.

Note - smul and sdiv treat the values as “signed” integers

Comparison Instructions
Comparison pop one or two values from the stack, performs a comparison and based on the result, pushes either true (0) or false
lt / slt: pushes true if the top stack value is less than the second.

gt / sgt: pushes true if the top stack value is greater than the second.

eq: pushes true if the top two stack values are equal.

iszero: pushes true if the top stack value is zero.

Bitwise Instructions
Bitwise instructions pop one or more values from the stack and performs bitwise operations on them.
and: performs bitwise AND on the top two stack values.

or: performs bitwise OR on the top two stack values.

xor: performs bitwise Exclusive OR on the top two stack values.

not: performs bitwise NOT on the top stack value. - shr / shl performs a bit-shift right and left, respectively.

shr / shl performs a bit-shift right and left, respectively. Top element of stack is tell the number of shifts.

Memory Instructions
Memory instructions read and write to a chunk of memory. Memory expands linearly and can be read / written to arbitrarily.
mstore: stores a 32 byte (256 bit) word in memory.

mstore8: stores a one byte (8 bit) word in memory.

mload: loads a 32 byte word from memory.

Context Instructions (Read)
The following is a non-comprehensive, short list of instructions that can read from the global state and execution context.
caller: pushes the address that called the current context.

timestamp: pushes the current block’s timestamp.

staticcall: can make a read-only call to another contract.

calldataload: can load a chunk of the calldata in the current context. - sload can read a piece of data from persistent storage on the current contract.

Context Instructions (Write)
The following is a non-comprehensive, short list of instructions that can write to the global state and the execution context.
sstore: can store data to persistent storage.

logN: can append data to the current transaction logs where N is the number of special, indexed values in the log.

call: can make a call to external code, which can also update the global state.

create / create2: can deploy code to a new address, creating a new contract.

My 2 cents :
mstore will take all 32 bytes , to ensure it takes less space , we can use code like mstore8
things we have talked today are more EVM - assembly specific and not "CODE" specific.

So that's all for this week folks , Stay tuned for more.

Top comments (0)