1

Taken from this repository

    /// @notice Generate number
function asmbl() public view returns (uint8 b) {
    assembly {
        let c := add(27, 16)
        mstore(0x80, c)
        { let d := add(sload(c), 255) b := d }
        b := add(b, c) }
    }

My understanding is:

  1. let c := add(27, 16). c stores now the value 42
  2. mstore(0x80, c). c was stored in memoryon address 0x80. Probably an useles statement without an effect. Because the memory is not used afterwards.
  3. let d := add(sload(c), 255).

sload(c). loads the length of c??? Not sure about this, but I read somewhere that sloading the varible without an offset returns the length of it. But if true, the sload(c) value is probably 256, because int256

add(sload(c), 255) is the same as add(256, 255) = 511. d = 511

  1. b := d. this is simple. value of d is assigned to b.
  2. b := add(b, c). b is 511 + 42 = 553
  3. 553 is returned by the function

Is this correct?

2 Answers 2

1
let c := add(27, 16)                 // 43 -> c
mstore(0x80, c)                      // stores uint256(43) at memory[0x80..0xa0]
{ 
  let d := add(sload(c), 255)        // sload(c) -> 0 (*)
                                     // 255 -> d
  b := d                             // 255 -> b
}
b := add(b, c)                       // 255 + 43 = 298 = 42 -> b (**)

(*) The contract has 12 variables, each occupies a single slot. So most slots above 13 are uninitialized and they will return 0. Some strings are initialized but they are short (less than 32) so no higher slots are used.

(**) b is uint8 so we can't store 298, it higher bits are truncated.

4
  • Is sload(c) loading the 43 slot? This video says that loading just the variable returns the size of the variable. Is this not correct? youtube.com/… Commented Nov 23, 2022 at 6:42
  • @Predicate sload != mload. sload(k) reads 32 bytes from persistent storage at slot k, and mload(j) reads 32 bytes from memory at address j.
    – Ismael
    Commented Nov 23, 2022 at 7:24
  • @j yes, but the source of loading is different. But the behaviour should be similar Commented Nov 24, 2022 at 14:15
  • @Predicate The way solidity uses memory is different than storage.
    – Ismael
    Commented Nov 24, 2022 at 15:40
0

I believe sload(c) loads the value stored at key c. The key is c and storage value is 42. Your mention about length is for dynamic arrays, but I don't think it’s applicable to this snippet here. Hence, d = 42 + 255 = 297, and b = 297 + 42 = 339, which is the value returned by the function.

See:

https://www.evm.codes/#54

8
  • This video says that the mload(bytes_variable) loads his length youtube.com/… Commented Nov 22, 2022 at 17:12
  • Actually I know the answer now. But I cant fully explain it to myself. The answer is 42. I think there is some overflow happening, because of uint8. maybe 255 + 256 + 43 and then overflowing uint8 to 42 Commented Nov 22, 2022 at 17:13
  • do we have a mload opcode here? Commented Nov 22, 2022 at 17:14
  • I don’t think overflow applies to assembly code. Commented Nov 22, 2022 at 17:14
  • As far as I understan mload and sload could be interchangable here. But I am not sure... Commented Nov 22, 2022 at 17:15

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.