This is designed to convert an address to a dynamic bytes type. Addresses are 20 bytes long, and occupy the right-most 20 bytes of a 32-byte word:
The bytes type is two (or more) words: the number of bytes followed by the data. The number of bytes in an address is 20 = 0x14, so it need to look like this in memory.
The final thing to know is that Solidity stores the current top of memory in the location 0x40. So
m is the top of memory, and is also where we are going to store the bytes version of
What we want to end up with is:
m+0 : 0x0000000000000000000000000000000000000000000000000000000000000014
m+32 : 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000
So here are the steps:
let m := mload(0x40) - sets
m to current top of memory
xor(0x140000000000000000000000000000000000000000, a) - puts 0x14 in front of the 20 bytes of address data and returns a 32-byte word padded with leading zeroes:
add(m, 20) - when the result of the
xor is written, it is shifted 20 bytes relative to the top of memory. This is both clever and dangerous; there's no guarantee that the memory at
m was empty, and we are not competely over-writing it. Anyway, this puts the 0x14 where we want it at the end of the word and followed by the
aaaas overflowing into the next word.
mstore(0x40, add(m, 52)) - finally we update the top of memory pointer; we've added 52 bytes in total (32 + 20). This would be better as
add(m, 64) in my view in case anything elsewhere relies on memory being word-aligned, but I may be over-cautious.
b := m - finally return the (pointer to the) result.
In short, this is very smart, but I would definitely zero-out the two words at top of memory before doing this to avoid any possible issues.