def reg_load(self, reg, value):
        """
        Load a value into a register. The value can be a string or binary (in
        which case the value is passed to :meth:`alloc_data`), another
        :class:`Register`, an :class:`Offset` or :class:`Buffer`, an integer
        immediate, a ``list`` or ``tuple`` or a syscall invocation.

        Arguments:
            reg(pwnypack.shellcode.types.Register): The register to load the
                value into.
            value: The value to load into the register.

        Returns:
            list: A list of mnemonics that will load value into reg.
        """

        if isinstance(value, (six.text_type, six.binary_type)):
            value = self.alloc_data(value)

        if value is None:
            return self.reg_load_imm(reg, 0)

        elif isinstance(value, Register):
            if reg is not value:
                return self.reg_load_reg(reg, value)
            else:
                return []

        elif isinstance(value, Offset):
            if value:
                return self.reg_load_offset(reg, value)
            else:
                return self.reg_load(reg, self.OFFSET_REG)

        elif isinstance(value, Buffer):
            return self.reg_load_offset(reg, sum(len(v) for v in six.iterkeys(self.data)) + value.offset)

        elif isinstance(value, six.integer_types):
            reg_width = self.REGISTER_WIDTH[reg]
            if value < -2 ** (reg_width-1):
                raise ValueError('%d does not fit %s' % (value, reg))
            elif value >= 2 ** reg_width:
                raise ValueError('%d does not fit %s' % (value, reg))
            return self.reg_load_imm(reg, value)

        elif isinstance(value, (list, tuple)):
            return self.reg_load_array(reg, value)

        elif isinstance(value, SyscallInvoke):
            return self.syscall(value) + self.reg_load(reg, self.SYSCALL_RET_REG)

        else:
            raise TypeError('Invalid argument type "%s"' % repr(value))