This header file:
https://github.com/micropython/micropyt ... .h#L51-L93 describes the various in-memory representations of the objects in MicroPython.
MicroPython was designed to run on a 32-bit MCU and assumes that pointers to objects will be 4-byte aligned. Which, in turn, means that the bottom 2 bits of an object pointer will always be 00. Changing the value of the bottom 2 bits allows integers and qstrs to be encoded in the same space as a pointer (instead of having to have a pointer point to an object containing the int or qstr).