def mem(data):
    """Parse a memory access string of format ``[EXPR]`` or ``seg:[EXPR]``

       ``EXPR`` may describe: ``BASE | INDEX * SCALE | DISPLACEMENT`` or any combinaison (in this order)
    """
    if not isinstance(data, str):
        raise TypeError("mem need a string to parse")
    data = data.strip()
    prefix = None
    if not (data.startswith("[") and data.endswith("]")):
        if data[2] != ":":
            raise ValueError("mem acces expect <[EXPR]> or <seg:[EXPR]")
        prefix_name = data[:2].upper()
        if prefix_name not in x86_segment_selectors:
            raise ValueError("Unknow segment selector {0}".format(prefix_name))
        prefix = prefix_name
        data = data[3:]
    if not (data.startswith("[") and data.endswith("]")):
        raise ValueError("mem acces expect <[EXPR]> or <seg:[EXPR]")
    # A l'arrache.. j'aime pas le parsing de trucs
    data = data[1:-1]
    items = data.split("+")
    parsed_items = {'prefix': prefix}
    for item in items:
        item = item.strip()
        # Index * scale
        if "*" in item:
            if 'index' in parsed_items:
                raise ValueError("Multiple index / index*scale in mem expression <{0}>".format(data))
            sub_items = item.split("*")
            if len(sub_items) != 2:
                raise ValueError("Invalid item <{0}> in mem access".format(item))
            index, scale = sub_items
            index, scale = index.strip(), scale.strip()
            if not X86.is_reg(index):
                raise ValueError("Invalid index <{0}> in mem access".format(index))
            if X86.reg_size(index) == 16:
                raise NotImplementedError("16bits modrm")
            try:
                scale = int(scale, 0)
            except ValueError:
                raise ValueError("Invalid scale <{0}> in mem access".format(scale))
            parsed_items['scale'] = scale
            parsed_items['index'] = index
        else:
            # displacement / base / index alone
            if X86.is_reg(item):
                if X86.reg_size(item) == 16:
                    raise NotImplementedError("16bits modrm")
                if 'base' not in parsed_items:
                    parsed_items['base'] = item
                    continue
                # Already have base + index -> cannot avec another register in expression
                if 'index' in parsed_items:
                    raise ValueError("Multiple index / index*scale in mem expression <{0}>".format(data))
                parsed_items['index'] = item
                continue
            try:
                disp = int(item, 0)
            except __HOLE__:
                raise ValueError("Invalid base/index or displacement <{0}> in mem access".format(item))
            if 'disp' in parsed_items:
                raise ValueError("Multiple displacement in mem expression <{0}>".format(data))
            parsed_items['disp'] = disp
    return create_displacement(**parsed_items)


# Helper to get the BitArray associated to a register
dataset/ETHPy150Open hakril/PythonForWindows/windows/native_exec/simple_x86.py/mem