1

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.

Debugging in Remix shows what gets stored where

Why is this so?

2 Answers 2

1

I think it works exactly as described by the EVM bytecode MSTORE:

  • MSTORE (uint256 offset, uint256 value) -> memory[offset:offset+32] = value
  • EVM uses big-endian, your value is 0x0443455243 = 0x0000000000000000000000000000000000000000000000000000000443455243
  • So memory[0x24:0x24+0x20 (32)] = 0x0000000000000000000000000000000000000000000000000000000443455243
  • Notice that your data has 27 (0x1B) leading zero bytes => the first byte (0x04) will be at address : 0x24 + 0x1B = 0x3F
  • So the layout will be 0x20: 00, 0x21: 00 ... 0x3F: 04, 0x40: 43, 0x41: 45, 0x42: 52, 0x43: 43
0

mstore always 32 bytes of word hence 0x0443455243 will be added a zero padding to make it 32 bytes.

Memory is like an array, you can access and store at any point (as long as you have enough gas). Even though remix show it as 0x0 block, 0x20 in block, it is just a sequence of numbers, following image of memory gives a better view

Image 1

As it is like a sequence of numbers (unlike storage - which can be allocated with 32 bytes words in a given slot), you can start writing from anywhere.

In the above example, I have added a 32 bytes word and 5 bytes word to the memory in different indexes.

If you execute the following opcodes in a transaction it would look like the following

push1 0x24
mload

(or mload 0x24)

Image 3

memory allocation is always of 32 bytes or multiples of it. If you want 1 byte in fresh memory it will allocate 32 bytes, similarly 33 bytes will get an allocation till 0x40th index (64 bytes of allocation of memory in full). In your case you are trying to store a 32 bytes value in the memory slot 0x24 (index 36). Which means the storing start at the index 0x24 and spreads till 0x44*(68 index). As Memory is allocated in 32 bytes of word from 0x44(index 68)* - 0x60(index 96) will be filled up with zeros.

if you want only to use up to 0x40 you can do a several mstore8 opcodes instead. note that mstore8 also costs 3 gas same as mstore(with no memory expansion)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.