For bytes1[], uint[] etc
For bytes and string arrays
0x000x20, 0x40, 0x60)0x80, where "abc" starts
0x80)0xA0)0xC0, where "de" starts
0xC0)0xE0)0x100, where "fgh" starts
0x100)0x120)0x140)assembly { ... }, where the code inside the curly braces is code in the Yul language.library GetCode {
function at(address _addr) public view returns (bytes o_code) {
assembly {
// retrieve the size of the code deployed at _addr, this needs assembly
let size := extcodesize(_addr)
// Loads the free memory pointer (always stored at position 0x40) into o_code.
o_code := mload(0x40)
// new "memory end" including padding
//Updates the free memory pointer to a new location:
//add(size, 0x20) accounts for the 32-byte length prefix of dynamic arrays.
//add(..., 0x1f) and and(..., not(0x1f)) rounds up to the nearest multiple of 32 (padding).
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
// Stores the length of the byte array (size) at the beginning of o_code (Solidity dynamic arrays start with a 32-byte length prefix).
mstore(o_code, size)
// Copies the actual bytecode at _addr into memory:
//Starts writing at o_code + 32, skipping over the length prefix.
//Starts reading code at offset 0 and copies size bytes.
extcodecopy(_addr, add(o_code, 0x20), 0, size)
}
}
}
Round any number to nearest multiple of 32. You do