Take this line for example (Yul):
mstore(0x24, 0x0443455243)
If it was mstore(0x20, 0x0443455243)
, then the entire value would have been stored at location 0x20
.
However, if 0x24
is used, I'd expect the value to be stored at 0x24
, but only the first byte is stored at 0x20
, whereas the next 4 bytes spill over and get stored at the end of location 0x40
.
Why is this so?
The Data in Memory and Storage is being saved a little bit differently. Though the memory is allocated in 32-byte sized buffer, there are no slots in memory, similar to storage. That's why talking about the end or start of location X is not quite correct, as a location is a position of a single byte. Remix simply splits the memory representation into blocks for better visual representation.
By storing a value (that is <= 32bytes), you specify the position(index), EVM picks a 32byte sized buffer starting from that position and packs the value to the end of that buffer.
mstore(0x20, 0x0443455243)
takes the buffer range at indexes 32..63
(in decimals).
mstore(0x24, 0x0443455243)
takes the buffer range 36..67
/0x24..0x43
.
Your binary (0x0443455243
) takes 5 bytes (string length 04
, and the data 43 45 52 43
), so when we place them into the 36..67
range, it will occupy the end of that buffer range, and the positions will be: 63,64,65,66,67
.
63
(0x3f
) is in the range end 0x20-0x3f
64..67
/(0x40..0x43
) are in the range start 0x40-0x5f