# How does this assembly function work?

From the Docs, how does this operation create a new "memory end"?

``````mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))
``````

Context:

``````library GetCode {
function at(address _addr) public view returns (bytes memory o_code) {
assembly {
// retrieve the size of the code, this needs assembly
let size := extcodesize(_addr)
// allocate output byte array - this could also be done without assembly
// by using o_code = new bytes(size)
// new "memory end" including padding
``````

I can follow the operators and parse the hexadecimal, however I'm never sure if I should be performing these on underlying values or the memory address values themselves (eg. 0x20 + 0x40 = 0x60).

It explained a little later in the same documentation:

Solidity manages memory in a very simple way: There is a “free memory pointer” at position 0x40 in memory. If you want to allocate memory, just use the memory starting from where this pointer points at and update it accordingly.

An array always use the first slot to store its length and it always aligned to 32 bytes (one slot).

In pseudo code it does something like this:

• Read free memory pointer

``````array_memory = memory[0x40]
``````
• Calculate array size in memory, add an extra 32 bytes for the array length and round it to 32 bytes. The mathematical formula is `trunc((code_size + 32 + 32 - 1) / 32) * 32`. And optimized to EVM assembly it is

``````array_size = (code_size + 0x20 + 0x1f) & ~0x1f
``````
• Update free memory pointer

``````memory[0x40] += array_size
``````
• Thank you. The formula you included is a very elegant means of explanation. My obstacles are conceptually mapping the logical bitwise operators to the formula. (Are the operands aligned, added, converted to binary and compared bit by bit to ~0x1f (binary)? Further, what is the role of ~0x1f.) – Zach_is_my_name May 20 '19 at 18:58
• Search for bit mask, for example en.wikipedia.org/wiki/Mask_(computing). For example `3` has all "lower" bits set to 1 (00011), the negation `~3` will flip those bytes to 0 (11100). Now masking `(x & ~3)` will set the lower bits of x to 0. – Ismael May 20 '19 at 19:11
• Now I've got it. Appreciate your time – Zach_is_my_name May 20 '19 at 19:16