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/… 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
    Nov 23, 2022 at 7:24
  • @j yes, but the source of loading is different. But the behaviour should be similar Nov 24, 2022 at 14:15
  • @Predicate The way solidity uses memory is different than storage.
    – Ismael
    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/… 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 Nov 22, 2022 at 17:13
  • do we have a mload opcode here? Nov 22, 2022 at 17:14
  • I don’t think overflow applies to assembly code. Nov 22, 2022 at 17:14
  • As far as I understan mload and sload could be interchangable here. But I am not sure... Nov 22, 2022 at 17:15

Your Answer

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

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