if isinstance(c, int):<EOL><INDENT>return bytes([c])<EOL><DEDENT>elif isinstance(c, str):<EOL><INDENT>return bytes([ord(c)])<EOL><DEDENT>else:<EOL><INDENT>return c<EOL><DEDENT>

Convert a byte-like value into a canonical byte (a value of type 'bytes' of len 1)

:param c:
:return:


def __init__(self, message, address=None):

self.address = address<EOL>self.message = message<EOL>if address is not None and not issymbolic(address):<EOL><INDENT>self.message += f'<STR_LIT>'<EOL><DEDENT>

Builds a memory exception.

:param message: exception message.
:param address: memory address where the exception occurred.


def __init__(self, start, size, perms, name=None):

assert isinstance(start, int) and start >= <NUM_LIT:0>, '<STR_LIT>'<EOL>assert isinstance(size, int) and size > <NUM_LIT:0>, '<STR_LIT>'<EOL>super().__init__()<EOL>self._start = start<EOL>self._end = start + size<EOL>self._set_perms(perms)<EOL>self._name = name<EOL>

Abstract memory map.

:param start: the first valid address.
:param size: the size of the map.
:param perms: the access permissions of the map (rwx).


return self._perms<EOL>


assert isinstance(perms, str) and len(perms) <= <NUM_LIT:3> and perms.strip() in ['<STR_LIT>', '<STR_LIT:r>', '<STR_LIT:w>', '<STR_LIT:x>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', ]<EOL>self._perms = perms<EOL>

Sets the access permissions of the map.

:param perms: the new permissions.


for c in access:<EOL><INDENT>if c not in self.perms:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL>

Check if there is enough permissions for access


return self._end - self._start<EOL>


return f'<STR_LIT>'<EOL>

Returns the string representation of the map mapping.

:rtype: str


return iter(range(self._start, self._end))<EOL>


if isinstance(index, slice):<EOL><INDENT>in_range = index.start < index.stop andindex.start >= self.start andindex.stop <= self.end<EOL><DEDENT>else:<EOL><INDENT>in_range = index >= self.start andindex <= self.end<EOL><DEDENT>return in_range<EOL>


if not self._in_range(index):<EOL><INDENT>raise IndexError('<STR_LIT>')<EOL><DEDENT>if isinstance(index, slice):<EOL><INDENT>index = slice(index.start - self.start, index.stop - self.start)<EOL><DEDENT>else:<EOL><INDENT>index -= self.start<EOL><DEDENT>return index<EOL>

Translates the index to the internal offsets.

self.start   -> 0
self.start+1 -> 1
...
self.end     -> len(self)


Reads a byte from an address or a sequence of bytes from a range of addresses

:param index: the address or slice where to obtain the bytes from.
:return: the character or sequence at the specified address.
:rtype: byte or array


@abstractmethod<EOL><INDENT>def __setitem__(self, index, value):<DEDENT>

Writes a byte to an address or a sequence of bytes to a range of addresses

:param index: the address or slice where to put the data.
:param value: byte or sequence of bytes to put in this map.


Split the current map into two mappings

:param address: The address at which to split the Map.


def __init__(self, start, size, perms, data_init=None, name=None, **kwargs):

super().__init__(start, size, perms, name, **kwargs)<EOL>self._data = bytearray(size)<EOL>if data_init is not None:<EOL><INDENT>assert len(data_init) <= size, '<STR_LIT>'<EOL>if isinstance(data_init[<NUM_LIT:0>], int):<EOL><INDENT>self._data[<NUM_LIT:0>:len(data_init)] = data_init<EOL><DEDENT>else:<EOL><INDENT>self._data[<NUM_LIT:0>:len(data_init)] = [ord(s) for s in data_init]<EOL><DEDENT><DEDENT>

Builds a concrete anonymous memory map.

:param start: the first valid address of the map.
:param size: the size of the map.
:param perms: the access permissions of the map.
:param data_init: the data to initialize the map.


def __init__(self, addr, size, perms, filename, offset=<NUM_LIT:0>, overlay=None, **kwargs):

super().__init__(addr, size, perms, **kwargs)<EOL>assert isinstance(offset, int)<EOL>assert offset >= <NUM_LIT:0><EOL>self._filename = filename<EOL>self._offset = offset<EOL>with open(filename, '<STR_LIT:r>') as fileobject:<EOL><INDENT>fileobject.seek(<NUM_LIT:0>, <NUM_LIT:2>)<EOL>file_size = fileobject.tell()<EOL>self._mapped_size = min(size, file_size - offset)<EOL>self._data = mmap(fileobject.fileno(), offset, self._mapped_size)<EOL><DEDENT>if overlay is not None:<EOL><INDENT>self._overlay = dict(overlay)<EOL><DEDENT>else:<EOL><INDENT>self._overlay = dict()<EOL><DEDENT>

Builds a map of memory  initialized with the content of filename.

:param addr: the first valid address of the file map.
:param size: the size of the file map.
:param perms: the access permissions of the file map.
:param filename: the file to map in memory.
:param offset: the offset into the file where to start the mapping. \
        This offset must be a multiple of pagebitsize.


def __init__(self, parent, offset=<NUM_LIT:0>, perms=None, size=None, **kwargs):

assert isinstance(parent, Map)<EOL>assert offset >= <NUM_LIT:0> and offset < len(parent)<EOL>if size is None:<EOL><INDENT>size = len(parent) - offset<EOL><DEDENT>assert parent.start + offset + size <= parent.end<EOL>if perms is None:<EOL><INDENT>perms = parent.perms<EOL><DEDENT>super().__init__(parent.start + offset, size, perms, **kwargs)<EOL>self._parent = parent<EOL>self._parent.__setitem__ = False<EOL>self._cow = {}<EOL>

A copy on write copy of parent. Writes to the parent after a copy on
write are unspecified.

:param parent: the parent map.
:param offset: an offset within the parent map from where to create the new map.
:param perms: Permissions on new mapping, or None if inheriting.
:param size: the size of the new map or max.


def __init__(self, maps=None, cpu=StubCPU()):

super().__init__()<EOL>if maps is None:<EOL><INDENT>self._maps = set()<EOL><DEDENT>else:<EOL><INDENT>self._maps = set(maps)<EOL><DEDENT>self.cpu = cpu<EOL>self._page2map = WeakValueDictionary()  <EOL>self._recording_stack = []<EOL>for m in self._maps:<EOL><INDENT>for i in range(self._page(m.start), self._page(m.end)):<EOL><INDENT>assert i not in self._page2map<EOL>self._page2map[i] = m<EOL><DEDENT><DEDENT>


return (((address - <NUM_LIT:1>) + self.page_size) & ~self.page_mask) & self.memory_mask<EOL>

Returns the smallest page boundary value not less than the address.
:rtype: int
:param address: the address to calculate its ceil.
:return: the ceil of C{address}.


return address & ~self.page_mask<EOL>

Returns largest page boundary value not greater than the address.

:param address: the address to calculate its floor.
:return: the floor of C{address}.
:rtype: int


return address >> self.page_bit_size<EOL>

Calculates the page number of an address.

:param address: the address to calculate its page number.
:return: the page number of address.
:rtype: int


def _search(self, size, start=None, counter=<NUM_LIT:0>):

assert size & self.page_mask == <NUM_LIT:0><EOL>if start is None:<EOL><INDENT>end = {<NUM_LIT:32>: <NUM_LIT>, <NUM_LIT:64>: <NUM_LIT>}[self.memory_bit_size]<EOL>start = end - size<EOL><DEDENT>else:<EOL><INDENT>if start > self.memory_size - size:<EOL><INDENT>start = self.memory_size - size<EOL><DEDENT>end = start + size<EOL><DEDENT>consecutive_free = <NUM_LIT:0><EOL>for p in range(self._page(end - <NUM_LIT:1>), -<NUM_LIT:1>, -<NUM_LIT:1>):<EOL><INDENT>if p not in self._page2map:<EOL><INDENT>consecutive_free += <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>consecutive_free = <NUM_LIT:0><EOL><DEDENT>if consecutive_free >= size:<EOL><INDENT>return p << self.page_bit_size<EOL><DEDENT>counter += <NUM_LIT:1><EOL>if counter >= self.memory_size // self.page_size:<EOL><INDENT>raise MemoryException('<STR_LIT>')<EOL><DEDENT><DEDENT>return self._search(size, self.memory_size - size, counter)<EOL>

Recursively searches the address space for enough free space to allocate C{size} bytes.

:param size: the size in bytes to allocate.
:param start: an address from where to start the search.
:param counter: internal parameter to know if all the memory was already scanned.
:return: the address of an available space to map C{size} bytes.
:raises MemoryException: if there is no space available to allocate the desired memory.
:rtype: int

todo: Document what happens when you try to allocate something that goes round the address 32/64 bit representation.


def mmapFile(self, addr, size, perms, filename, offset=<NUM_LIT:0>):

<EOL>assert addr is None or isinstance(addr, int), '<STR_LIT>'<EOL>assert size > <NUM_LIT:0><EOL>self.cpu._publish('<STR_LIT>', addr, size, perms, filename, offset)<EOL>if addr is not None:<EOL><INDENT>assert addr < self.memory_size, '<STR_LIT>'<EOL>addr = self._floor(addr)<EOL><DEDENT>size = self._ceil(size)<EOL>addr = self._search(size, addr)<EOL>for i in range(self._page(addr), self._page(addr + size)):<EOL><INDENT>assert i not in self._page2map, '<STR_LIT>'<EOL><DEDENT>m = FileMap(addr, size, perms, filename, offset)<EOL>self._add(m)<EOL>logger.debug('<STR_LIT>', addr, size)<EOL>self.cpu._publish('<STR_LIT>', addr, size, perms, filename, offset, addr)<EOL>return addr<EOL>

Creates a new file mapping in the memory address space.

:param addr: the starting address (took as hint). If C{addr} is C{0} the first big enough
             chunk of memory will be selected as starting address.
:param size: the contents of a file mapping are initialized using C{size} bytes starting
             at offset C{offset} in the file C{filename}.
:param perms: the access permissions to this memory.
:param filename: the pathname to the file to map.
:param offset: the contents of a file mapping are initialized using C{size} bytes starting
              at offset C{offset} in the file C{filename}.
:return: the starting address where the file was mapped.
:rtype: int
:raises error:
           - 'Address shall be concrete' if C{addr} is not an integer number.
           - 'Address too big' if C{addr} goes beyond the limit of the memory.
           - 'Map already used' if the piece of memory starting in C{addr} and with length C{size} isn't free.


def mmap(self, addr, size, perms, data_init=None, name=None):

<EOL>assert addr is None or isinstance(addr, int), '<STR_LIT>'<EOL>self.cpu._publish('<STR_LIT>', addr, size, perms, None, None)<EOL>if addr is not None:<EOL><INDENT>assert addr < self.memory_size, '<STR_LIT>'<EOL>addr = self._floor(addr)<EOL><DEDENT>size = self._ceil(size)<EOL>addr = self._search(size, addr)<EOL>for i in range(self._page(addr), self._page(addr + size)):<EOL><INDENT>assert i not in self._page2map, '<STR_LIT>'<EOL><DEDENT>m = AnonMap(start=addr, size=size, perms=perms, data_init=data_init, name=name)<EOL>self._add(m)<EOL>logger.debug('<STR_LIT>', addr, size)<EOL>self.cpu._publish('<STR_LIT>', addr, size, perms, None, None, addr)<EOL>return addr<EOL>

Creates a new mapping in the memory address space.

:param addr: the starting address (took as hint). If C{addr} is C{0} the first big enough
             chunk of memory will be selected as starting address.
:param size: the length of the mapping.
:param perms: the access permissions to this memory.
:param data_init: optional data to initialize this memory.
:param name: optional name to give to this mapping
:return: the starting address where the memory was mapped.
:raises error:
           - 'Address shall be concrete' if C{addr} is not an integer number.
           - 'Address too big' if C{addr} goes beyond the limit of the memory.
           - 'Map already used' if the piece of memory starting in C{addr} and with length C{size} isn't free.
:rtype: int


page_offset = self._page(address)<EOL>if page_offset not in self._page2map:<EOL><INDENT>raise MemoryException("<STR_LIT>", address)<EOL><DEDENT>return self._page2map[page_offset]<EOL>

Returns the L{MMap} object containing the address.

:param address: the address to obtain its mapping.
:rtype: L{MMap}

@todo: symbolic address


result = []<EOL>for m in self.maps:<EOL><INDENT>if isinstance(m, AnonMap):<EOL><INDENT>result.append((m.start, m.end, m.perms, <NUM_LIT:0>, '<STR_LIT>'))<EOL><DEDENT>elif isinstance(m, FileMap):<EOL><INDENT>result.append((m.start, m.end, m.perms, m._offset, m._filename))<EOL><DEDENT>else:<EOL><INDENT>result.append((m.start, m.end, m.perms, <NUM_LIT:0>, m.name))<EOL><DEDENT><DEDENT>return sorted(result)<EOL>

Returns a sorted list of all the mappings for this memory.

:return: a list of mappings.
:rtype: list


<EOL>addr = start<EOL>while addr < end:<EOL><INDENT>if addr not in self:<EOL><INDENT>addr += self.page_size<EOL><DEDENT>else:<EOL><INDENT>m = self._page2map[self._page(addr)]<EOL>yield m<EOL>addr = m.end<EOL><DEDENT><DEDENT>

Generates the list of maps that overlaps with the range [start:end]


start = self._floor(start)<EOL>end = self._ceil(start + size)<EOL>self.cpu._publish('<STR_LIT>', start, size)<EOL>for m in self._maps_in_range(start, end):<EOL><INDENT>self._del(m)<EOL>head, tail = m.split(start)<EOL>middle, tail = tail.split(end)<EOL>assert middle is not None<EOL>if head:<EOL><INDENT>self._add(head)<EOL><DEDENT>if tail:<EOL><INDENT>self._add(tail)<EOL><DEDENT><DEDENT>self.cpu._publish('<STR_LIT>', start, size)<EOL>logger.debug(f'<STR_LIT>')<EOL>

Deletes the mappings for the specified address range and causes further
references to addresses within the range to generate invalid memory
references.

:param start: the starting address to delete.
:param size: the length of the unmapping.


Begin recording all writes. Retrieve all writes with `pop_record_writes()`


lst = self._recording_stack.pop()<EOL>if self._recording_stack:<EOL><INDENT>self._recording_stack[-<NUM_LIT:1>].extend(lst)<EOL><DEDENT>return lst<EOL>

Stop recording trace and return a `list[(address, value)]` of all the writes
that occurred, where `value` is of type list[str]. Can be called without
intermediate `pop_record_writes()`.

For example::

    mem.push_record_writes()
        mem.write(1, 'a')
        mem.push_record_writes()
            mem.write(2, 'b')
        mem.pop_record_writes()  # Will return [(2, 'b')]
    mem.pop_record_writes()  # Will return [(1, 'a'), (2, 'b')]

Multiple writes to the same address will all be included in the trace in the
same order they occurred.

:return: list[tuple]


for page_addr in sorted(self._page2map.keys()):<EOL><INDENT>start = page_addr * self.page_size<EOL>end = start + self.page_size<EOL>for addr in range(start, end):<EOL><INDENT>yield addr<EOL><DEDENT><DEDENT>


def __init__(self, constraints, symbols=None, *args, **kwargs):

super().__init__(*args, **kwargs)<EOL>assert isinstance(constraints, ConstraintSet)<EOL>self._constraints = constraints<EOL>if symbols is None:<EOL><INDENT>self._symbols = {}<EOL><DEDENT>else:<EOL><INDENT>self._symbols = dict(symbols)<EOL><DEDENT>

Builds a memory.

:param constraints:  a set of constraints
:param symbols: Symbolic chunks


for addr in range(start, start + size):<EOL><INDENT>if len(self._symbols) == <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT>if addr in self._symbols:<EOL><INDENT>del self._symbols[addr]<EOL><DEDENT><DEDENT>super().munmap(start, size)<EOL>


def read(self, address, size, force=False):

size = self._get_size(size)<EOL>assert not issymbolic(size)<EOL>if issymbolic(address):<EOL><INDENT>assert solver.check(self.constraints)<EOL>logger.debug(f'<STR_LIT>')<EOL>try:<EOL><INDENT>solutions = self._try_get_solutions(address, size, '<STR_LIT:r>', force=force)<EOL>assert len(solutions) > <NUM_LIT:0><EOL><DEDENT>except TooManySolutions as e:<EOL><INDENT>m, M = solver.minmax(self.constraints, address)<EOL>logger.debug(f'<STR_LIT>')<EOL>crashing_condition = True<EOL>for start, end, perms, offset, name in self.mappings():<EOL><INDENT>if start <= M + size and end >= m:<EOL><INDENT>if '<STR_LIT:r>' in perms:<EOL><INDENT>crashing_condition = Operators.AND(Operators.OR((address + size).ult(start), address.uge(end)), crashing_condition)<EOL><DEDENT><DEDENT><DEDENT>if solver.can_be_true(self.constraints, crashing_condition):<EOL><INDENT>raise InvalidSymbolicMemoryAccess(address, '<STR_LIT:r>', size, crashing_condition)<EOL><DEDENT>logger.info('<STR_LIT>')<EOL>condition = False<EOL>for base in e.solutions:<EOL><INDENT>condition = Operators.OR(address == base, condition)<EOL><DEDENT>from .state import ForkState<EOL>raise ForkState("<STR_LIT>", condition)<EOL><DEDENT>condition = False<EOL>for base in solutions:<EOL><INDENT>condition = Operators.OR(address == base, condition)<EOL><DEDENT>result = []<EOL>for offset in range(size):<EOL><INDENT>for base in solutions:<EOL><INDENT>addr_value = base + offset<EOL>byte = Operators.ORD(self.map_containing(addr_value)[addr_value])<EOL>if addr_value in self._symbols:<EOL><INDENT>for condition, value in self._symbols[addr_value]:<EOL><INDENT>byte = Operators.ITEBV(<NUM_LIT:8>, condition, Operators.ORD(value), byte)<EOL><DEDENT><DEDENT>if len(result) > offset:<EOL><INDENT>result[offset] = Operators.ITEBV(<NUM_LIT:8>, address == base, byte, result[offset])<EOL><DEDENT>else:<EOL><INDENT>result.append(byte)<EOL><DEDENT>assert len(result) == offset + <NUM_LIT:1><EOL><DEDENT><DEDENT>return list(map(Operators.CHR, result))<EOL><DEDENT>else:<EOL><INDENT>result = list(map(Operators.ORD, super().read(address, size, force)))<EOL>for offset in range(size):<EOL><INDENT>if address + offset in self._symbols:<EOL><INDENT>for condition, value in self._symbols[address + offset]:<EOL><INDENT>if condition is True:<EOL><INDENT>result[offset] = Operators.ORD(value)<EOL><DEDENT>else:<EOL><INDENT>result[offset] = Operators.ITEBV(<NUM_LIT:8>, condition, Operators.ORD(value), result[offset])<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return list(map(Operators.CHR, result))<EOL><DEDENT>

Read a stream of potentially symbolic bytes from a potentially symbolic
address

:param address: Where to read from
:param size: How many bytes
:param force: Whether to ignore permissions
:rtype: list


def write(self, address, value, force=False):

size = len(value)<EOL>if issymbolic(address):<EOL><INDENT>solutions = self._try_get_solutions(address, size, '<STR_LIT:w>', force=force)<EOL>for offset in range(size):<EOL><INDENT>for base in solutions:<EOL><INDENT>condition = base == address<EOL>self._symbols.setdefault(base + offset, []).append((condition, value[offset]))<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>for offset in range(size):<EOL><INDENT>if issymbolic(value[offset]):<EOL><INDENT>if not self.access_ok(address + offset, '<STR_LIT:w>', force):<EOL><INDENT>raise InvalidMemoryAccess(address + offset, '<STR_LIT:w>')<EOL><DEDENT>self._symbols[address + offset] = [(True, value[offset])]<EOL><DEDENT>else:<EOL><INDENT>if address + offset in self._symbols:<EOL><INDENT>del self._symbols[address + offset]<EOL><DEDENT>super().write(address + offset, [value[offset]], force)<EOL><DEDENT><DEDENT><DEDENT>

Write a value at address.
:param address: The address at which to write
:type address: int or long or Expression
:param value: Bytes to write
:type value: str or list
:param force: Whether to ignore permissions


def _try_get_solutions(self, address, size, access, max_solutions=<NUM_LIT>, force=False):

assert issymbolic(address)<EOL>solutions = solver.get_all_values(self.constraints, address, maxcnt=max_solutions)<EOL>crashing_condition = False<EOL>for base in solutions:<EOL><INDENT>if not self.access_ok(slice(base, base + size), access, force):<EOL><INDENT>crashing_condition = Operators.OR(address == base, crashing_condition)<EOL><DEDENT><DEDENT>if solver.can_be_true(self.constraints, crashing_condition):<EOL><INDENT>raise InvalidSymbolicMemoryAccess(address, access, size, crashing_condition)<EOL><DEDENT>return solutions<EOL>

Try to solve for a symbolic address, checking permissions when reading/writing size bytes.

:param Expression address: The address to solve for
:param int size: How many bytes to check permissions for
:param str access: 'r' or 'w'
:param int max_solutions: Will raise if more solutions are found
:param force: Whether to ignore permission failure
:rtype: list


<EOL>assert addr is None or isinstance(addr, int), '<STR_LIT>'<EOL>assert addr < self.memory_size, '<STR_LIT>'<EOL>assert size > <NUM_LIT:0><EOL>self.cpu._publish('<STR_LIT>', addr, size, perms, filename, offset)<EOL>map = AnonMap(addr, size, perms)<EOL>self._add(map)<EOL>if addr is not None:<EOL><INDENT>addr = self._floor(addr)<EOL><DEDENT>size = self._ceil(size)<EOL>with open(filename, '<STR_LIT:rb>') as f:<EOL><INDENT>fdata = f.read()  <EOL><DEDENT>fdata = fdata[offset:]<EOL>fdata = fdata.ljust(size, b'<STR_LIT>')<EOL>for i in range(size):<EOL><INDENT>Memory.write(self, addr + i, chr(fdata[i]), force=True)<EOL><DEDENT>logger.debug('<STR_LIT>', addr, size)<EOL>self.cpu._publish('<STR_LIT>', addr, size, perms, filename, offset, addr)<EOL>return addr<EOL>


def _import_concrete_memory(self, from_addr, to_addr):

logger.debug("<STR_LIT>".format(from_addr, to_addr, to_addr - from_addr))<EOL>for m in self.maps:<EOL><INDENT>span = interval_intersection(m.start, m.end, from_addr, to_addr)<EOL>if span is None:<EOL><INDENT>continue<EOL><DEDENT>start, stop = span<EOL>for addr in range(start, stop):<EOL><INDENT>if addr in self.backed_by_symbolic_store:<EOL><INDENT>continue<EOL><DEDENT>self.backing_array[addr] = Memory.read(self, addr, <NUM_LIT:1>)[<NUM_LIT:0>]<EOL>self.backed_by_symbolic_store.add(addr)<EOL><DEDENT><DEDENT>

for each address in this range need to read from concrete and write to symbolic
it's possible that there will be invalid/unmapped addresses in this range. need to skip to next map if so
also need to mark all of these addresses as now in the symbolic store

:param int from_addr:
:param int to_addr:
:return:


<EOL>if isinstance(data_to_find, bytes):<EOL><INDENT>data_to_find = [bytes([c]) for c in data_to_find]<EOL><DEDENT>for mapping in sorted(self.maps):<EOL><INDENT>for ptr in mapping:<EOL><INDENT>if ptr + len(data_to_find) >= mapping.end:<EOL><INDENT>break<EOL><DEDENT>candidate = mapping[ptr:ptr + len(data_to_find)]<EOL>if issymbolic(candidate[<NUM_LIT:0>]):<EOL><INDENT>break<EOL><DEDENT>if candidate == data_to_find:<EOL><INDENT>yield ptr<EOL><DEDENT><DEDENT><DEDENT>

Scan for concrete bytes in all mapped memory. Successively yield addresses of all matches.

:param bytes data_to_find: String to locate
:return:


def make_symbolic(flag_expr):<EOL><INDENT>register_size = <NUM_LIT:32> if reg == '<STR_LIT>' else <NUM_LIT:64><EOL>value, offset = flag_expr<EOL>return Operators.ITEBV(register_size, value,<EOL>BitVecConstant(register_size, <NUM_LIT:1> << offset),<EOL>BitVecConstant(register_size, <NUM_LIT:0>))<EOL><DEDENT>flags = []<EOL>for flag, offset in self._flags.items():<EOL><INDENT>flags.append((self._registers[flag], offset))<EOL><DEDENT>if any(issymbolic(flag) for flag, offset in flags):<EOL><INDENT>res = reduce(operator.or_, map(make_symbolic, flags))<EOL><DEDENT>else:<EOL><INDENT>res = <NUM_LIT:0><EOL>for flag, offset in flags:<EOL><INDENT>res += flag << offset<EOL><DEDENT><DEDENT>return res<EOL>


<EOL>for flag, offset in self._flags.items():<EOL><INDENT>self.write(flag, Operators.EXTRACT(res, offset, <NUM_LIT:1>))<EOL><DEDENT>

Set individual flags from a EFLAGS/RFLAGS value


def __init__(self, regfile, memory, *args, **kwargs):

super().__init__(regfile, memory, *args, **kwargs)<EOL>self._segments = {}<EOL>

Builds a CPU model.
:param regfile: regfile object for this CPU.
:param memory: memory object for this CPU.


assert size in (<NUM_LIT:8>, <NUM_LIT:16>, cpu.address_bit_size)<EOL>cpu.STACK = cpu.STACK - size // <NUM_LIT:8><EOL>base, _, _ = cpu.get_descriptor(cpu.read_register('<STR_LIT>'))<EOL>address = cpu.STACK + base<EOL>cpu.write_int(address, value, size)<EOL>

Writes a value in the stack.

:param value: the value to put in the stack.
:param size: the size of the value.


assert size in (<NUM_LIT:16>, cpu.address_bit_size)<EOL>base, _, _ = cpu.get_descriptor(cpu.SS)<EOL>address = cpu.STACK + base<EOL>value = cpu.read_int(address, size)<EOL>cpu.STACK = cpu.STACK + size // <NUM_LIT:8><EOL>return value<EOL>

Gets a value from the stack.

:rtype: int
:param size: the size of the value to consume from the stack.
:return: the value from the stack.


def invalidate_cache(cpu, address, size):

cache = cpu.instruction_cache<EOL>for offset in range(size):<EOL><INDENT>if address + offset in cache:<EOL><INDENT>del cache[address + offset]<EOL><DEDENT><DEDENT>

remove decoded instruction from instruction cache


<EOL>conf = {<NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: {<NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>)},<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: {<NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>)},<EOL><NUM_LIT>: {<NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>),<EOL><NUM_LIT>: (<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>)},<EOL>}<EOL>if cpu.EAX not in conf:<EOL><INDENT>logger.warning('<STR_LIT>', cpu.EAX, cpu.PC)<EOL>cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0><EOL>return<EOL><DEDENT>if isinstance(conf[cpu.EAX], tuple):<EOL><INDENT>cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = conf[cpu.EAX]<EOL>return<EOL><DEDENT>if cpu.ECX not in conf[cpu.EAX]:<EOL><INDENT>logger.warning('<STR_LIT>', cpu.EAX, cpu.ECX)<EOL>cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0><EOL>return<EOL><DEDENT>cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = conf[cpu.EAX][cpu.ECX]<EOL>

CPUID instruction.

The ID flag (bit 21) in the EFLAGS register indicates support for the
CPUID instruction.  If a software procedure can set and clear this
flag, the processor executing the procedure supports the CPUID
instruction. This instruction operates the same in non-64-bit modes and
64-bit mode.  CPUID returns processor identification and feature
information in the EAX, EBX, ECX, and EDX registers.

The instruction's output is dependent on the contents of the EAX
register upon execution.

:param cpu: current CPU.


<EOL>cpu.EAX, cpu.EDX = <NUM_LIT:7>, <NUM_LIT:0><EOL>

XGETBV instruction.

Reads the contents of the extended cont register (XCR) specified in the ECX register into registers EDX:EAX.
Implemented only for ECX = 0.

:param cpu: current CPU.


@instruction<EOL><INDENT>def AND(cpu, dest, src):<DEDENT>

<EOL>if src.size == <NUM_LIT:64> and src.type == '<STR_LIT>' and dest.size == <NUM_LIT:64>:<EOL><INDENT>arg1 = Operators.SEXTEND(src.read(), <NUM_LIT:32>, <NUM_LIT:64>)<EOL><DEDENT>else:<EOL><INDENT>arg1 = src.read()<EOL><DEDENT>res = dest.write(dest.read() & arg1)<EOL>cpu._calculate_logic_flags(dest.size, res)<EOL>

Logical AND.

Performs a bitwise AND operation on the destination (first) and source
(second) operands and stores the result in the destination operand location.
Each bit of the result is set to 1 if both corresponding bits of the first and
second operands are 1; otherwise, it is set to 0.

The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

    DEST  =  DEST AND SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


res = dest.write(~dest.read())<EOL>

One's complement negation.

Performs a bitwise NOT operation (each 1 is cleared to 0, and each 0
is set to 1) on the destination operand and stores the result in the destination
operand location::

    DEST  =  NOT DEST;

:param cpu: current CPU.
:param dest: destination operand.


@instruction<EOL><INDENT>def XOR(cpu, dest, src):<DEDENT>

if dest == src:<EOL><INDENT>res = dest.write(<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>res = dest.write(dest.read() ^ src.read())<EOL><DEDENT>cpu._calculate_logic_flags(dest.size, res)<EOL>

Logical exclusive OR.

Performs a bitwise exclusive Operators.OR(XOR) operation on the destination (first)
and source (second) operands and stores the result in the destination
operand location.

Each bit of the result is 1 if the corresponding bits of the operands
are different; each bit is 0 if the corresponding bits are the same.

The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

    DEST  =  DEST XOR SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def OR(cpu, dest, src):<DEDENT>

res = dest.write(dest.read() | src.read())<EOL>cpu._calculate_logic_flags(dest.size, res)<EOL>

Logical inclusive OR.

Performs a bitwise inclusive OR operation between the destination (first)
and source (second) operands and stores the result in the destination operand location.

Each bit of the result of the OR instruction is set to 0 if both corresponding
bits of the first and second operands are 0; otherwise, each bit is set
to 1.

The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

    DEST  =  DEST OR SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


cpu.AF = Operators.OR(cpu.AL & <NUM_LIT> > <NUM_LIT:9>, cpu.AF)<EOL>cpu.CF = cpu.AF<EOL>cpu.AH = Operators.ITEBV(<NUM_LIT:8>, cpu.AF, cpu.AH + <NUM_LIT:1>, cpu.AH)<EOL>cpu.AL = Operators.ITEBV(<NUM_LIT:8>, cpu.AF, cpu.AL + <NUM_LIT:6>, cpu.AL)<EOL>"""<STR_LIT>"""<EOL>cpu.AL = cpu.AL & <NUM_LIT><EOL>

ASCII adjust after addition.

Adjusts the sum of two unpacked BCD values to create an unpacked BCD
result. The AL register is the implied source and destination operand
for this instruction. The AAA instruction is only useful when it follows
an ADD instruction that adds (binary addition) two unpacked BCD values
and stores a byte result in the AL register. The AAA instruction then
adjusts the contents of the AL register to contain the correct 1-digit
unpacked BCD result.
If the addition produces a decimal carry, the AH register is incremented
by 1, and the CF and AF flags are set. If there was no decimal carry,
the CF and AF flags are cleared and the AH register is unchanged. In either
case, bits 4 through 7 of the AL register are cleared to 0.

This instruction executes as described in compatibility mode and legacy mode.
It is not valid in 64-bit mode.
::
        IF ((AL AND 0FH) > 9) Operators.OR(AF  =  1)
        THEN
            AL  =  (AL + 6);
            AH  =  AH + 1;
            AF  =  1;
            CF  =  1;
        ELSE
            AF  =  0;
            CF  =  0;
        FI;
        AL  =  AL AND 0FH;
:param cpu: current CPU.


if imm is None:<EOL><INDENT>imm = <NUM_LIT:10><EOL><DEDENT>else:<EOL><INDENT>imm = imm.read()<EOL><DEDENT>cpu.AL += cpu.AH * imm<EOL>cpu.AH = <NUM_LIT:0><EOL>cpu._calculate_logic_flags(<NUM_LIT:8>, cpu.AL)<EOL>

ASCII adjust AX before division.

Adjusts two unpacked BCD digits (the least-significant digit in the
AL register and the most-significant digit in the AH register) so that
a division operation performed on the result will yield a correct unpacked
BCD value. The AAD instruction is only useful when it precedes a DIV instruction
that divides (binary division) the adjusted value in the AX register by
an unpacked BCD value.
The AAD instruction sets the value in the AL register to (AL + (10 * AH)), and then
clears the AH register to 00H. The value in the AX register is then equal to the binary
equivalent of the original unpacked two-digit (base 10) number in registers AH and AL.

The SF, ZF, and PF flags are set according to the resulting binary value in the AL register.

This instruction executes as described in compatibility mode and legacy mode.
It is not valid in 64-bit mode.::

        tempAL  =  AL;
        tempAH  =  AH;
        AL  =  (tempAL + (tempAH * 10)) AND FFH;
        AH  =  0

:param cpu: current CPU.


if imm is None:<EOL><INDENT>imm = <NUM_LIT:10><EOL><DEDENT>else:<EOL><INDENT>imm = imm.read()<EOL><DEDENT>cpu.AH = Operators.UDIV(cpu.AL, imm)<EOL>cpu.AL = Operators.UREM(cpu.AL, imm)<EOL>cpu._calculate_logic_flags(<NUM_LIT:8>, cpu.AL)<EOL>

ASCII adjust AX after multiply.

Adjusts the result of the multiplication of two unpacked BCD values
to create a pair of unpacked (base 10) BCD values. The AX register is
the implied source and destination operand for this instruction. The AAM
instruction is only useful when it follows a MUL instruction that multiplies
(binary multiplication) two unpacked BCD values and stores a word result
in the AX register. The AAM instruction then adjusts the contents of the
AX register to contain the correct 2-digit unpacked (base 10) BCD result.

The SF, ZF, and PF flags are set according to the resulting binary value in the AL register.

This instruction executes as described in compatibility mode and legacy mode.
It is not valid in 64-bit mode.::

        tempAL  =  AL;
        AH  =  tempAL / 10;
        AL  =  tempAL MOD 10;

:param cpu: current CPU.


if (cpu.AL & <NUM_LIT> > <NUM_LIT:9>) or cpu.AF == <NUM_LIT:1>:<EOL><INDENT>cpu.AX = cpu.AX - <NUM_LIT:6><EOL>cpu.AH = cpu.AH - <NUM_LIT:1><EOL>cpu.AF = True<EOL>cpu.CF = True<EOL><DEDENT>else:<EOL><INDENT>cpu.AF = False<EOL>cpu.CF = False<EOL><DEDENT>cpu.AL = cpu.AL & <NUM_LIT><EOL>

ASCII Adjust AL after subtraction.

Adjusts the result of the subtraction of two unpacked BCD values to  create a unpacked
BCD result. The AL register is the implied source and destination operand for this instruction.
The AAS instruction is only useful when it follows a SUB instruction that subtracts
(binary subtraction) one unpacked BCD value from another and stores a byte result in the AL
register. The AAA instruction then adjusts the contents of the AL register to contain the
correct 1-digit unpacked BCD result. If the subtraction produced a decimal carry, the AH register
is decremented by 1, and the CF and AF flags are set. If no decimal carry occurred, the CF and AF
flags are cleared, and the AH register is unchanged. In either case, the AL register is left with
its top nibble set to 0.

The AF and CF flags are set to 1 if there is a decimal borrow; otherwise, they are cleared to 0.

This instruction executes as described in compatibility mode and legacy mode.
It is not valid in 64-bit mode.::

        IF ((AL AND 0FH) > 9) Operators.OR(AF  =  1)
        THEN
            AX  =  AX - 6;
            AH  =  AH - 1;
            AF  =  1;
            CF  =  1;
        ELSE
            CF  =  0;
            AF  =  0;
        FI;
        AL  =  AL AND 0FH;

:param cpu: current CPU.


@instruction<EOL><INDENT>def ADC(cpu, dest, src):<DEDENT>

cpu._ADD(dest, src, carry=True)<EOL>

Adds with carry.

Adds the destination operand (first operand), the source operand (second operand),
and the carry (CF) flag and stores the result in the destination operand. The state
of the CF flag represents a carry from a previous addition. When an immediate value
is used as an operand, it is sign-extended to the length of the destination operand
format. The ADC instruction does not distinguish between signed or unsigned operands.
Instead, the processor evaluates the result for both data types and sets the OF and CF
flags to indicate a carry in the signed or unsigned result, respectively. The SF flag
indicates the sign of the signed result. The ADC instruction is usually executed as
part of a multibyte or multiword addition in which an ADD instruction is followed by an
ADC instruction::

        DEST  =  DEST + SRC + CF;

The OF, SF, ZF, AF, CF, and PF flags are set according to the result.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def ADD(cpu, dest, src):<DEDENT>

cpu._ADD(dest, src, carry=False)<EOL>

Add.

Adds the first operand (destination operand) and the second operand (source operand)
and stores the result in the destination operand. When an immediate value is used as
an operand, it is sign-extended to the length of the destination operand format.
The ADD instruction does not distinguish between signed or unsigned operands. Instead,
the processor evaluates the result for both data types and sets the OF and CF flags to
indicate a carry in the signed or unsigned result, respectively. The SF flag indicates
the sign of the signed result::

        DEST  =  DEST + SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMP(cpu, src1, src2):<DEDENT>

arg0 = src1.read()<EOL>arg1 = Operators.SEXTEND(src2.read(), src2.size, src1.size)<EOL>cpu._calculate_CMP_flags(src1.size, arg0 - arg1, arg0, arg1)<EOL>

Compares two operands.

Compares the first source operand with the second source operand and sets the status flags
in the EFLAGS register according to the results. The comparison is performed by subtracting
the second operand from the first operand and then setting the status flags in the same manner
as the SUB instruction. When an immediate value is used as an operand, it is sign-extended to
the length of the first operand::

        temp  =  SRC1 - SignExtend(SRC2);
        ModifyStatusFlags; (* Modify status flags in the same manner as the SUB instruction*)

The CF, OF, SF, ZF, AF, and PF flags are set according to the result.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMPXCHG(cpu, dest, src):<DEDENT>

size = dest.size<EOL>reg_name = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[size]<EOL>accumulator = cpu.read_register(reg_name)<EOL>sval = src.read()<EOL>dval = dest.read()<EOL>cpu.write_register(reg_name, dval)<EOL>dest.write(Operators.ITEBV(size, accumulator == dval, sval, dval))<EOL>cpu._calculate_CMP_flags(size, accumulator - dval, accumulator, dval)<EOL>

Compares and exchanges.

Compares the value in the AL, AX, EAX or RAX register (depending on the
size of the operand) with the first operand (destination operand). If
the two values are equal, the second operand (source operand) is loaded
into the destination operand. Otherwise, the destination operand is
loaded into the AL, AX, EAX or RAX register.

The ZF flag is set if the values in the destination operand and
register AL, AX, or EAX are equal; otherwise it is cleared. The CF, PF,
AF, SF, and OF flags are set according to the results of the comparison
operation::

(* accumulator  =  AL, AX, EAX or RAX,  depending on whether *)
(* a byte, word, a doubleword or a 64bit comparison is being performed*)
IF accumulator  ==  DEST
THEN
    ZF  =  1
    DEST  =  SRC
ELSE
    ZF  =  0
    accumulator  =  DEST
FI;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


size = dest.size<EOL>cmp_reg_name_l = {<NUM_LIT:64>: '<STR_LIT>', <NUM_LIT>: '<STR_LIT>'}[size]<EOL>cmp_reg_name_h = {<NUM_LIT:64>: '<STR_LIT>', <NUM_LIT>: '<STR_LIT>'}[size]<EOL>src_reg_name_l = {<NUM_LIT:64>: '<STR_LIT>', <NUM_LIT>: '<STR_LIT>'}[size]<EOL>src_reg_name_h = {<NUM_LIT:64>: '<STR_LIT>', <NUM_LIT>: '<STR_LIT>'}[size]<EOL>cmph = cpu.read_register(cmp_reg_name_h)<EOL>cmpl = cpu.read_register(cmp_reg_name_l)<EOL>srch = cpu.read_register(src_reg_name_h)<EOL>srcl = cpu.read_register(src_reg_name_l)<EOL>cmp0 = Operators.CONCAT(size, cmph, cmpl)<EOL>src0 = Operators.CONCAT(size, srch, srcl)<EOL>arg_dest = dest.read()<EOL>cpu.ZF = arg_dest == cmp0<EOL>dest.write(<EOL>Operators.ITEBV(size, cpu.ZF,<EOL>Operators.CONCAT(size, srch, srcl),<EOL>arg_dest)<EOL>)<EOL>cpu.write_register(cmp_reg_name_l, Operators.ITEBV(size // <NUM_LIT:2>, cpu.ZF, cmpl,<EOL>Operators.EXTRACT(arg_dest, <NUM_LIT:0>, size // <NUM_LIT:2>)))<EOL>cpu.write_register(cmp_reg_name_h, Operators.ITEBV(size // <NUM_LIT:2>, cpu.ZF, cmph,<EOL>Operators.EXTRACT(arg_dest, size // <NUM_LIT:2>, size // <NUM_LIT:2>)))<EOL>

Compares and exchanges bytes.

Compares the 64-bit value in EDX:EAX (or 128-bit value in RDX:RAX if
operand size is 128 bits) with the operand (destination operand). If
the values are equal, the 64-bit value in ECX:EBX (or 128-bit value in
RCX:RBX) is stored in the destination operand.  Otherwise, the value in
the destination operand is loaded into EDX:EAX (or RDX:RAX)::

        IF (64-Bit Mode and OperandSize = 64)
        THEN
            IF (RDX:RAX = DEST)
            THEN
                ZF = 1;
                DEST = RCX:RBX;
            ELSE
                ZF = 0;
                RDX:RAX = DEST;
            FI
        ELSE
            IF (EDX:EAX = DEST)
            THEN
                ZF = 1;
                DEST = ECX:EBX;
            ELSE
                ZF = 0;
                EDX:EAX = DEST;
            FI;
        FI;

:param cpu: current CPU.
:param dest: destination operand.


cpu.AF = Operators.OR((cpu.AL & <NUM_LIT>) > <NUM_LIT:9>, cpu.AF)<EOL>oldAL = cpu.AL<EOL>cpu.AL = Operators.ITEBV(<NUM_LIT:8>, cpu.AF, cpu.AL + <NUM_LIT:6>, cpu.AL)<EOL>cpu.CF = Operators.ITE(cpu.AF, Operators.OR(cpu.CF, cpu.AL < oldAL), cpu.CF)<EOL>cpu.CF = Operators.OR((cpu.AL & <NUM_LIT>) > <NUM_LIT>, cpu.CF)<EOL>cpu.AL = Operators.ITEBV(<NUM_LIT:8>, cpu.CF, cpu.AL + <NUM_LIT>, cpu.AL)<EOL>"""<STR_LIT>"""<EOL>cpu.ZF = cpu.AL == <NUM_LIT:0><EOL>cpu.SF = (cpu.AL & <NUM_LIT>) != <NUM_LIT:0><EOL>cpu.PF = cpu._calculate_parity_flag(cpu.AL)<EOL>

Decimal adjusts AL after addition.

Adjusts the sum of two packed BCD values to create a packed BCD result. The AL register
is the implied source and destination operand. If a decimal carry is detected, the CF
and AF flags are set accordingly.
The CF and AF flags are set if the adjustment of the value results in a decimal carry in
either digit of the result. The SF, ZF, and PF flags are set according to the result.

This instruction is not valid in 64-bit mode.::

        IF (((AL AND 0FH) > 9) or AF  =  1)
        THEN
            AL  =  AL + 6;
            CF  =  CF OR CarryFromLastAddition; (* CF OR carry from AL  =  AL + 6 *)
            AF  =  1;
        ELSE
            AF  =  0;
        FI;
        IF ((AL AND F0H) > 90H) or CF  =  1)
        THEN
            AL  =  AL + 60H;
            CF  =  1;
        ELSE
            CF  =  0;
        FI;

:param cpu: current CPU.


oldAL = cpu.AL<EOL>oldCF = cpu.CF<EOL>cpu.AF = Operators.OR((cpu.AL & <NUM_LIT>) > <NUM_LIT:9>, cpu.AF)<EOL>cpu.AL = Operators.ITEBV(<NUM_LIT:8>, cpu.AF, cpu.AL - <NUM_LIT:6>, cpu.AL)<EOL>cpu.CF = Operators.ITE(cpu.AF, Operators.OR(oldCF, cpu.AL > oldAL), cpu.CF)<EOL>cpu.CF = Operators.ITE(Operators.OR(oldAL > <NUM_LIT>, oldCF), True, cpu.CF)<EOL>cpu.AL = Operators.ITEBV(<NUM_LIT:8>, Operators.OR(oldAL > <NUM_LIT>, oldCF), cpu.AL - <NUM_LIT>, cpu.AL)<EOL>"""<STR_LIT>"""<EOL>cpu.ZF = cpu.AL == <NUM_LIT:0><EOL>cpu.SF = (cpu.AL & <NUM_LIT>) != <NUM_LIT:0><EOL>cpu.PF = cpu._calculate_parity_flag(cpu.AL)<EOL>

Decimal adjusts AL after subtraction.

Adjusts the result of the subtraction of two packed BCD values to create a packed BCD result.
The AL register is the implied source and destination operand. If a decimal borrow is detected,
the CF and AF flags are set accordingly. This instruction is not valid in 64-bit mode.

The SF, ZF, and PF flags are set according to the result.::

        IF (AL AND 0FH) > 9 OR AF  =  1
        THEN
            AL  =  AL - 6;
            CF  =  CF OR BorrowFromLastSubtraction; (* CF OR borrow from AL  =  AL - 6 *)
            AF  =  1;
        ELSE
            AF  =  0;
        FI;
        IF ((AL > 99H) or OLD_CF  =  1)
        THEN
            AL  =  AL - 60H;
            CF  =  1;

:param cpu: current CPU.


arg0 = dest.read()<EOL>res = dest.write(arg0 - <NUM_LIT:1>)<EOL>res &= (<NUM_LIT:1> << dest.size) - <NUM_LIT:1><EOL>SIGN_MASK = <NUM_LIT:1> << (dest.size - <NUM_LIT:1>)<EOL>cpu.AF = ((arg0 ^ <NUM_LIT:1>) ^ res) & <NUM_LIT> != <NUM_LIT:0><EOL>cpu.ZF = res == <NUM_LIT:0><EOL>cpu.SF = (res & SIGN_MASK) != <NUM_LIT:0><EOL>cpu.OF = res == SIGN_MASK<EOL>cpu.PF = cpu._calculate_parity_flag(res)<EOL>

Decrements by 1.

Subtracts 1 from the destination operand, while preserving the state of
the CF flag. The destination operand can be a register or a memory
location. This instruction allows a loop counter to be updated without
disturbing the CF flag. (To perform a decrement operation that updates
the CF flag, use a SUB instruction with an immediate operand of 1.) The
instruction's 64-bit mode default operation size is 32 bits.

The OF, SF, ZF, AF, and PF flags are set according to the result::

        DEST  =  DEST - 1;

:param cpu: current CPU.
:param dest: destination operand.


size = src.size<EOL>reg_name_h = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[size]<EOL>reg_name_l = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[size]<EOL>dividend = Operators.CONCAT(size * <NUM_LIT:2>,<EOL>cpu.read_register(reg_name_h),<EOL>cpu.read_register(reg_name_l))<EOL>divisor = Operators.ZEXTEND(src.read(), size * <NUM_LIT:2>)<EOL>if isinstance(divisor, int) and divisor == <NUM_LIT:0>:<EOL><INDENT>raise DivideByZeroError()<EOL><DEDENT>quotient = Operators.UDIV(dividend, divisor)<EOL>MASK = (<NUM_LIT:1> << size) - <NUM_LIT:1><EOL>if isinstance(quotient, int) and quotient > MASK:<EOL><INDENT>raise DivideByZeroError()<EOL><DEDENT>remainder = Operators.UREM(dividend, divisor)<EOL>cpu.write_register(reg_name_l, Operators.EXTRACT(quotient, <NUM_LIT:0>, size))<EOL>cpu.write_register(reg_name_h, Operators.EXTRACT(remainder, <NUM_LIT:0>, size))<EOL>

Unsigned divide.

Divides (unsigned) the value in the AX register, DX:AX register pair,
or EDX:EAX or RDX:RAX register pair (dividend) by the source operand
(divisor) and stores the result in the AX (AH:AL), DX:AX, EDX:EAX or
RDX:RAX registers. The source operand can be a general-purpose register
or a memory location. The action of this instruction depends of the
operand size (dividend/divisor). Division using 64-bit operand is
available only in 64-bit mode. Non-integral results are truncated
(chopped) towards 0. The reminder is always less than the divisor in
magnitude. Overflow is indicated with the #DE (divide error) exception
rather than with the CF flag::

    IF SRC  =  0
        THEN #DE; FI;(* divide error *)
    IF OperandSize  =  8 (* word/byte operation *)
        THEN
            temp  =  AX / SRC;
            IF temp > FFH
                THEN #DE; (* divide error *) ;
                ELSE
                    AL  =  temp;
                    AH  =  AX MOD SRC;
            FI;
        ELSE IF OperandSize  =  16 (* doubleword/word operation *)
            THEN
                temp  =  DX:AX / SRC;
                IF temp > FFFFH
                    THEN #DE; (* divide error *) ;
                ELSE
                    AX  =  temp;
                    DX  =  DX:AX MOD SRC;
                FI;
            FI;
        ELSE If OperandSize = 32 (* quadword/doubleword operation *)
            THEN
                temp  =  EDX:EAX / SRC;
                IF temp > FFFFFFFFH
                    THEN #DE; (* divide error *) ;
                ELSE
                    EAX  =  temp;
                    EDX  =  EDX:EAX MOD SRC;
                FI;
            FI;
        ELSE IF OperandSize = 64 (*Doublequadword/quadword operation*)
            THEN
                temp = RDX:RAX / SRC;
                IF temp > FFFFFFFFFFFFFFFFH
                    THEN #DE; (* Divide error *)
                ELSE
                    RAX = temp;
                    RDX = RDX:RAX MOD SRC;
                FI;
            FI;
    FI;

:param cpu: current CPU.
:param src: source operand.


reg_name_h = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[src.size]<EOL>reg_name_l = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[src.size]<EOL>dividend = Operators.CONCAT(src.size * <NUM_LIT:2>,<EOL>cpu.read_register(reg_name_h),<EOL>cpu.read_register(reg_name_l))<EOL>divisor = src.read()<EOL>if isinstance(divisor, int) and divisor == <NUM_LIT:0>:<EOL><INDENT>raise DivideByZeroError()<EOL><DEDENT>dst_size = src.size * <NUM_LIT:2><EOL>divisor = Operators.SEXTEND(divisor, src.size, dst_size)<EOL>mask = (<NUM_LIT:1> << dst_size) - <NUM_LIT:1><EOL>sign_mask = <NUM_LIT:1> << (dst_size - <NUM_LIT:1>)<EOL>dividend_sign = (dividend & sign_mask) != <NUM_LIT:0><EOL>divisor_sign = (divisor & sign_mask) != <NUM_LIT:0><EOL>if isinstance(divisor, int):<EOL><INDENT>if divisor_sign:<EOL><INDENT>divisor = ((~divisor) + <NUM_LIT:1>) & mask<EOL>divisor = -divisor<EOL><DEDENT><DEDENT>if isinstance(dividend, int):<EOL><INDENT>if dividend_sign:<EOL><INDENT>dividend = ((~dividend) + <NUM_LIT:1>) & mask<EOL>dividend = -dividend<EOL><DEDENT><DEDENT>quotient = Operators.SDIV(dividend, divisor)<EOL>if (isinstance(dividend, int) and<EOL>isinstance(dividend, int)):<EOL><INDENT>remainder = dividend - (quotient * divisor)<EOL><DEDENT>else:<EOL><INDENT>remainder = Operators.SREM(dividend, divisor)<EOL><DEDENT>cpu.write_register(reg_name_l, Operators.EXTRACT(quotient, <NUM_LIT:0>, src.size))<EOL>cpu.write_register(reg_name_h, Operators.EXTRACT(remainder, <NUM_LIT:0>, src.size))<EOL>

Signed divide.

Divides (signed) the value in the AL, AX, or EAX register by the source
operand and stores the result in the AX, DX:AX, or EDX:EAX registers.
The source operand can be a general-purpose register or a memory
location. The action of this instruction depends on the operand size.::

IF SRC  =  0
THEN #DE; (* divide error *)
FI;
IF OpernadSize  =  8 (* word/byte operation *)
THEN
    temp  =  AX / SRC; (* signed division *)
    IF (temp > 7FH) Operators.OR(temp < 80H)
    (* if a positive result is greater than 7FH or a negative result is
    less than 80H *)
    THEN #DE; (* divide error *) ;
    ELSE
        AL  =  temp;
        AH  =  AX SignedModulus SRC;
    FI;
ELSE
    IF OpernadSize  =  16 (* doubleword/word operation *)
    THEN
        temp  =  DX:AX / SRC; (* signed division *)
        IF (temp > 7FFFH) Operators.OR(temp < 8000H)
        (* if a positive result is greater than 7FFFH *)
        (* or a negative result is less than 8000H *)
        THEN #DE; (* divide error *) ;
        ELSE
            AX  =  temp;
            DX  =  DX:AX SignedModulus SRC;
        FI;
    ELSE (* quadword/doubleword operation *)
        temp  =  EDX:EAX / SRC; (* signed division *)
        IF (temp > 7FFFFFFFH) Operators.OR(temp < 80000000H)
        (* if a positive result is greater than 7FFFFFFFH *)
        (* or a negative result is less than 80000000H *)
        THEN #DE; (* divide error *) ;
        ELSE
            EAX  =  temp;
            EDX  =  EDX:EAX SignedModulus SRC;
        FI;
    FI;
FI;

:param cpu: current CPU.
:param src: source operand.


dest = operands[<NUM_LIT:0>]<EOL>OperandSize = dest.size<EOL>reg_name_h = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[OperandSize]<EOL>reg_name_l = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[OperandSize]<EOL>arg0 = dest.read()<EOL>arg1 = None<EOL>arg2 = None<EOL>res = None<EOL>if len(operands) == <NUM_LIT:1>:<EOL><INDENT>arg1 = cpu.read_register(reg_name_l)<EOL>temp = (Operators.SEXTEND(arg0, OperandSize, OperandSize * <NUM_LIT:2>) *<EOL>Operators.SEXTEND(arg1, OperandSize, OperandSize * <NUM_LIT:2>))<EOL>temp = temp & ((<NUM_LIT:1> << (OperandSize * <NUM_LIT:2>)) - <NUM_LIT:1>)<EOL>cpu.write_register(reg_name_l,<EOL>Operators.EXTRACT(temp, <NUM_LIT:0>, OperandSize))<EOL>cpu.write_register(reg_name_h,<EOL>Operators.EXTRACT(temp, OperandSize, OperandSize))<EOL>res = Operators.EXTRACT(temp, <NUM_LIT:0>, OperandSize)<EOL><DEDENT>elif len(operands) == <NUM_LIT:2>:<EOL><INDENT>arg1 = operands[<NUM_LIT:1>].read()<EOL>arg1 = Operators.SEXTEND(arg1, OperandSize, OperandSize * <NUM_LIT:2>)<EOL>temp = Operators.SEXTEND(arg0, OperandSize, OperandSize * <NUM_LIT:2>) * arg1<EOL>temp = temp & ((<NUM_LIT:1> << (OperandSize * <NUM_LIT:2>)) - <NUM_LIT:1>)<EOL>res = dest.write(Operators.EXTRACT(temp, <NUM_LIT:0>, OperandSize))<EOL><DEDENT>else:<EOL><INDENT>arg1 = operands[<NUM_LIT:1>].read()<EOL>arg2 = operands[<NUM_LIT:2>].read()<EOL>temp = (Operators.SEXTEND(arg1, OperandSize, OperandSize * <NUM_LIT:2>) *<EOL>Operators.SEXTEND(arg2, operands[<NUM_LIT:2>].size, OperandSize * <NUM_LIT:2>))<EOL>temp = temp & ((<NUM_LIT:1> << (OperandSize * <NUM_LIT:2>)) - <NUM_LIT:1>)<EOL>res = dest.write(Operators.EXTRACT(temp, <NUM_LIT:0>, OperandSize))<EOL><DEDENT>cpu.CF = (Operators.SEXTEND(res, OperandSize, OperandSize * <NUM_LIT:2>) != temp)<EOL>cpu.OF = cpu.CF<EOL>

Signed multiply.

Performs a signed multiplication of two operands. This instruction has
three forms, depending on the number of operands.
    - One-operand form. This form is identical to that used by the MUL
    instruction. Here, the source operand (in a general-purpose
    register or memory location) is multiplied by the value in the AL,
    AX, or EAX register (depending on the operand size) and the product
    is stored in the AX, DX:AX, or EDX:EAX registers, respectively.
    - Two-operand form. With this form the destination operand (the
    first operand) is multiplied by the source operand (second
    operand). The destination operand is a general-purpose register and
    the source operand is an immediate value, a general-purpose
    register, or a memory location. The product is then stored in the
    destination operand location.
    - Three-operand form. This form requires a destination operand (the
    first operand) and two source operands (the second and the third
    operands). Here, the first source operand (which can be a
    general-purpose register or a memory location) is multiplied by the
    second source operand (an immediate value). The product is then
    stored in the destination operand (a general-purpose register).

When an immediate value is used as an operand, it is sign-extended to
the length of the destination operand format. The CF and OF flags are
set when significant bits are carried into the upper half of the
result. The CF and OF flags are cleared when the result fits exactly in
the lower half of the result. The three forms of the IMUL instruction
are similar in that the length of the product is calculated to twice
the length of the operands. With the one-operand form, the product is
stored exactly in the destination. With the two- and three- operand
forms, however, result is truncated to the length of the destination
before it is stored in the destination register. Because of this
truncation, the CF or OF flag should be tested to ensure that no
significant bits are lost. The two- and three-operand forms may also be
used with unsigned operands because the lower half of the product is
the same regardless if the operands are signed or unsigned. The CF and
OF flags, however, cannot be used to determine if the upper half of the
result is non-zero::

IF (NumberOfOperands == 1)
THEN
    IF (OperandSize == 8)
    THEN
        AX = AL * SRC (* Signed multiplication *)
        IF AL == AX
        THEN
            CF = 0; OF = 0;
        ELSE
            CF = 1; OF = 1;
        FI;
    ELSE
        IF OperandSize == 16
        THEN
            DX:AX = AX * SRC (* Signed multiplication *)
            IF sign_extend_to_32 (AX) == DX:AX
            THEN
                CF = 0; OF = 0;
            ELSE
                CF = 1; OF = 1;
            FI;
        ELSE
            IF OperandSize == 32
            THEN
                EDX:EAX = EAX * SRC (* Signed multiplication *)
                IF EAX == EDX:EAX
                THEN
                    CF = 0; OF = 0;
                ELSE
                    CF = 1; OF = 1;
                FI;
            ELSE (* OperandSize = 64 *)
                RDX:RAX = RAX * SRC (* Signed multiplication *)
                IF RAX == RDX:RAX
                THEN
                    CF = 0; OF = 0;
                ELSE
                   CF = 1; OF = 1;
                FI;
            FI;
        FI;
ELSE
    IF (NumberOfOperands = 2)
    THEN
        temp = DEST * SRC (* Signed multiplication; temp is double DEST size *)
        DEST = DEST * SRC (* Signed multiplication *)
        IF temp != DEST
        THEN
            CF = 1; OF = 1;
        ELSE
            CF = 0; OF = 0;
        FI;
    ELSE (* NumberOfOperands = 3 *)
        DEST = SRC1 * SRC2 (* Signed multiplication *)
        temp = SRC1 * SRC2 (* Signed multiplication; temp is double SRC1 size *)
        IF temp != DEST
        THEN
            CF = 1; OF = 1;
        ELSE
            CF = 0; OF = 0;
        FI;
    FI;
FI;

:param cpu: current CPU.
:param operands: variable list of operands.


arg0 = dest.read()<EOL>res = dest.write(arg0 + <NUM_LIT:1>)<EOL>res &= (<NUM_LIT:1> << dest.size) - <NUM_LIT:1><EOL>SIGN_MASK = <NUM_LIT:1> << (dest.size - <NUM_LIT:1>)<EOL>cpu.AF = ((arg0 ^ <NUM_LIT:1>) ^ res) & <NUM_LIT> != <NUM_LIT:0><EOL>cpu.ZF = res == <NUM_LIT:0><EOL>cpu.SF = (res & SIGN_MASK) != <NUM_LIT:0><EOL>cpu.OF = res == SIGN_MASK<EOL>cpu.PF = cpu._calculate_parity_flag(res)<EOL>

Increments by 1.

Adds 1 to the destination operand, while preserving the state of the
CF flag. The destination operand can be a register or a memory location.
This instruction allows a loop counter to be updated without disturbing
the CF flag. (Use a ADD instruction with an immediate operand of 1 to
perform an increment operation that does updates the CF flag.)::

        DEST  =  DEST +1;

:param cpu: current CPU.
:param dest: destination operand.


size = src.size<EOL>reg_name_low, reg_name_high = {<NUM_LIT:8>: ('<STR_LIT>', '<STR_LIT>'),<EOL><NUM_LIT:16>: ('<STR_LIT>', '<STR_LIT>'),<EOL><NUM_LIT:32>: ('<STR_LIT>', '<STR_LIT>'),<EOL><NUM_LIT:64>: ('<STR_LIT>', '<STR_LIT>')}[size]<EOL>res = (Operators.ZEXTEND(cpu.read_register(reg_name_low), <NUM_LIT>) *<EOL>Operators.ZEXTEND(src.read(), <NUM_LIT>))<EOL>cpu.write_register(reg_name_low, Operators.EXTRACT(res, <NUM_LIT:0>, size))<EOL>cpu.write_register(reg_name_high, Operators.EXTRACT(res, size, size))<EOL>cpu.OF = Operators.EXTRACT(res, size, size) != <NUM_LIT:0><EOL>cpu.CF = cpu.OF<EOL>

Unsigned multiply.

Performs an unsigned multiplication of the first operand (destination
operand) and the second operand (source operand) and stores the result
in the destination operand. The destination operand is an implied operand
located in register AL, AX or EAX (depending on the size of the operand);
the source operand is located in a general-purpose register or a memory location.

The result is stored in register AX, register pair DX:AX, or register
pair EDX:EAX (depending on the operand size), with the high-order bits
of the product contained in register AH, DX, or EDX, respectively. If
the high-order bits of the product are 0, the CF and OF flags are cleared;
otherwise, the flags are set::

        IF byte operation
        THEN
            AX  =  AL * SRC
        ELSE (* word or doubleword operation *)
            IF OperandSize  =  16
            THEN
                DX:AX  =  AX * SRC
            ELSE (* OperandSize  =  32 *)
                EDX:EAX  =  EAX * SRC
            FI;
        FI;

:param cpu: current CPU.
:param src: source operand.


source = dest.read()<EOL>res = dest.write(-source)<EOL>cpu._calculate_logic_flags(dest.size, res)<EOL>cpu.CF = source != <NUM_LIT:0><EOL>cpu.AF = (res & <NUM_LIT>) != <NUM_LIT><EOL>

Two's complement negation.

Replaces the value of operand (the destination operand) with its two's complement.
(This operation is equivalent to subtracting the operand from 0.) The destination operand is
located in a general-purpose register or a memory location::

        IF DEST  =  0
        THEN CF  =  0
        ELSE CF  =  1;
        FI;
        DEST  =  - (DEST)

:param cpu: current CPU.
:param dest: destination operand.


@instruction<EOL><INDENT>def SBB(cpu, dest, src):<DEDENT>

cpu._SUB(dest, src, carry=True)<EOL>

Integer subtraction with borrow.

Adds the source operand (second operand) and the carry (CF) flag, and
subtracts the result from the destination operand (first operand). The
result of the subtraction is stored in the destination operand. The
destination operand can be a register or a memory location; the source
operand can be an immediate, a register, or a memory location.
(However, two memory operands cannot be used in one instruction.) The
state of the CF flag represents a borrow from a previous subtraction.
When an immediate value is used as an operand, it is sign-extended to
the length of the destination operand format.
The SBB instruction does not distinguish between signed or unsigned
operands. Instead, the processor evaluates the result for both data
types and sets the OF and CF flags to indicate a borrow in the signed
or unsigned result, respectively. The SF flag indicates the sign of the
signed result.  The SBB instruction is usually executed as part of a
multibyte or multiword subtraction in which a SUB instruction is
followed by a SBB instruction::

        DEST  =  DEST - (SRC + CF);

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def SUB(cpu, dest, src):<DEDENT>

cpu._SUB(dest, src, carry=False)<EOL>

Subtract.

Subtracts the second operand (source operand) from the first operand
(destination operand) and stores the result in the destination operand.
The destination operand can be a register or a memory location; the
source operand can be an immediate, register, or memory location.
(However, two memory operands cannot be used in one instruction.) When
an immediate value is used as an operand, it is sign-extended to the
length of the destination operand format.
The SUB instruction does not distinguish between signed or unsigned
operands. Instead, the processor evaluates the result for both
data types and sets the OF and CF flags to indicate a borrow in the
signed or unsigned result, respectively. The SF flag indicates the sign
of the signed result::

    DEST  =  DEST - SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def XADD(cpu, dest, src):<DEDENT>

MASK = (<NUM_LIT:1> << dest.size) - <NUM_LIT:1><EOL>SIGN_MASK = <NUM_LIT:1> << (dest.size - <NUM_LIT:1>)<EOL>arg0 = dest.read()<EOL>arg1 = src.read()<EOL>temp = (arg1 + arg0) & MASK<EOL>src.write(arg0)<EOL>dest.write(temp)<EOL>tempCF = Operators.OR(Operators.ULT(temp, arg0), Operators.ULT(temp, arg1))<EOL>cpu.CF = tempCF<EOL>cpu.AF = ((arg0 ^ arg1) ^ temp) & <NUM_LIT> != <NUM_LIT:0><EOL>cpu.ZF = temp == <NUM_LIT:0><EOL>cpu.SF = (temp & SIGN_MASK) != <NUM_LIT:0><EOL>cpu.OF = (((arg0 ^ arg1 ^ SIGN_MASK) & (temp ^ arg1)) & SIGN_MASK) != <NUM_LIT:0><EOL>cpu.PF = cpu._calculate_parity_flag(temp)<EOL>

Exchanges and adds.

Exchanges the first operand (destination operand) with the second operand
(source operand), then loads the sum of the two values into the destination
operand. The destination operand can be a register or a memory location;
the source operand is a register.
This instruction can be used with a LOCK prefix::

        TEMP  =  SRC + DEST
        SRC  =  DEST
        DEST  =  TEMP

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


parts = []<EOL>arg0 = dest.read()<EOL>for i in range(<NUM_LIT:0>, dest.size, <NUM_LIT:8>):<EOL><INDENT>parts.append(Operators.EXTRACT(arg0, i, <NUM_LIT:8>))<EOL><DEDENT>dest.write(Operators.CONCAT(<NUM_LIT:8> * len(parts), *parts))<EOL>

Byte swap.

Reverses the byte order of a 32-bit (destination) register: bits 0 through
7 are swapped with bits 24 through 31, and bits 8 through 15 are swapped
with bits 16 through 23. This instruction is provided for converting little-endian
values to big-endian format and vice versa.
To swap bytes in a word value (16-bit register), use the XCHG instruction.
When the BSWAP instruction references a 16-bit register, the result is
undefined::

    TEMP  =  DEST
    DEST[7..0]  =  TEMP[31..24]
    DEST[15..8]  =  TEMP[23..16]
    DEST[23..16]  =  TEMP[15..8]
    DEST[31..24]  =  TEMP[7..0]

:param cpu: current CPU.
:param dest: destination operand.


@instruction<EOL><INDENT>def CMOVB(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.CF, src.read(), dest.read()))<EOL>

Conditional move - Below/not above or equal.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVA(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.CF == False, cpu.ZF == False), src.read(), dest.read()))<EOL>

Conditional move - Above/not below or equal.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVAE(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.CF == False, src.read(), dest.read()))<EOL>

Conditional move - Above or equal/not below.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVBE(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF), src.read(), dest.read()))<EOL>

Conditional move - Below or equal/not above.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVZ(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.ZF, src.read(), dest.read()))<EOL>

Conditional move - Equal/zero.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVNZ(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.ZF == False, src.read(), dest.read()))<EOL>

Conditional move - Not equal/not zero.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVP(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.PF, src.read(), dest.read()))<EOL>

Conditional move - Parity/parity even.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVNP(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.PF == False, src.read(), dest.read()))<EOL>

Conditional move - Not parity/parity odd.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVG(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.ZF == <NUM_LIT:0>, cpu.SF == cpu.OF), src.read(), dest.read()))<EOL>

Conditional move - Greater.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVGE(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, (cpu.SF ^ cpu.OF) == <NUM_LIT:0>, src.read(), dest.read()))<EOL>

Conditional move - Greater or equal/not less.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVL(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.SF ^ cpu.OF, src.read(), dest.read()))<EOL>

Conditional move - Less/not greater or equal.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVLE(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.SF ^ cpu.OF, cpu.ZF), src.read(), dest.read()))<EOL>

Conditional move - Less or equal/not greater.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVO(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.OF, src.read(), dest.read()))<EOL>

Conditional move - Overflow.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVNO(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.OF == False, src.read(), dest.read()))<EOL>

Conditional move - Not overflow.

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVS(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.SF, src.read(), dest.read()))<EOL>

Conditional move - Sign (negative).

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def CMOVNS(cpu, dest, src):<DEDENT>

dest.write(Operators.ITEBV(dest.size, cpu.SF == False, src.read(), dest.read()))<EOL>

Conditional move - Not sign (non-negative).

Tests the status flags in the EFLAGS register and moves the source operand
(second operand) to the destination operand (first operand) if the given
test condition is true.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


used_regs = (cpu.SF, cpu.ZF, cpu.AF, cpu.PF, cpu.CF)<EOL>is_expression = any(issymbolic(x) for x in used_regs)<EOL>def make_flag(val, offset):<EOL><INDENT>if is_expression:<EOL><INDENT>return Operators.ITEBV(<NUM_LIT:8>, val,<EOL>BitVecConstant(<NUM_LIT:8>, <NUM_LIT:1> << offset),<EOL>BitVecConstant(<NUM_LIT:8>, <NUM_LIT:0>))<EOL><DEDENT>else:<EOL><INDENT>return val << offset<EOL><DEDENT><DEDENT>cpu.AH = (make_flag(cpu.SF, <NUM_LIT:7>) |<EOL>make_flag(cpu.ZF, <NUM_LIT:6>) |<EOL>make_flag(<NUM_LIT:0>, <NUM_LIT:5>) |<EOL>make_flag(cpu.AF, <NUM_LIT:4>) |<EOL>make_flag(<NUM_LIT:0>, <NUM_LIT:3>) |<EOL>make_flag(cpu.PF, <NUM_LIT:2>) |<EOL>make_flag(<NUM_LIT:1>, <NUM_LIT:1>) |<EOL>make_flag(cpu.CF, <NUM_LIT:0>))<EOL>

Loads status flags into AH register.

Moves the low byte of the EFLAGS register (which includes status flags
SF, ZF, AF, PF, and CF) to the AH register. Reserved bits 1, 3, and 5
of the EFLAGS register are set in the AH register::

        AH  =  EFLAGS(SF:ZF:0:AF:0:PF:1:CF);

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def LDS(cpu, dest, src):<DEDENT>

raise NotImplementedError("<STR_LIT>")<EOL>


@instruction<EOL><INDENT>def LES(cpu, dest, src):<DEDENT>


@instruction<EOL><INDENT>def LFS(cpu, dest, src):<DEDENT>


@instruction<EOL><INDENT>def LGS(cpu, dest, src):<DEDENT>


@instruction<EOL><INDENT>def LSS(cpu, dest, src):<DEDENT>

Loads far pointer.

Loads a far pointer (segment selector and offset) from the second operand
(source operand) into a segment register and the first operand (destination
operand). The source operand specifies a 48-bit or a 32-bit pointer in
memory depending on the current setting of the operand-size attribute
(32 bits or 16 bits, respectively). The instruction opcode and the destination
operand specify a segment register/general-purpose register pair. The
16-bit segment selector from the source operand is loaded into the segment
register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit
or 16-bit offset is loaded into the register specified with the destination
operand.
In 64-bit mode, the instruction's default operation size is 32 bits. Using a
REX prefix in the form of REX.W promotes operation to specify a source operand
referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory.
If one of these instructions is executed in protected mode, additional
information from the segment descriptor pointed to by the segment selector
in the source operand is loaded in the hidden part of the selected segment
register.
Also in protected mode, a null selector (values 0000 through 0003) can
be loaded into DS, ES, FS, or GS registers without causing a protection
exception. (Any subsequent reference to a segment whose corresponding
segment register is loaded with a null selector, causes a general-protection
exception (#GP) and no memory reference to the segment occurs.)::

        IF ProtectedMode
        THEN IF SS is loaded
            THEN IF SegementSelector  =  null
                THEN #GP(0);
                FI;
            ELSE IF Segment selector index is not within descriptor table limits
                OR Segment selector RPL  CPL
                OR Access rights indicate nonwritable data segment
                OR DPL  CPL
                THEN #GP(selector);
                FI;
            ELSE IF Segment marked not present
                THEN #SS(selector);
                FI;
                SS  =  SegmentSelector(SRC);
                SS  =  SegmentDescriptor([SRC]);
            ELSE IF DS, ES, FS, or GS is loaded with non-null segment selector
                THEN IF Segment selector index is not within descriptor table limits
                    OR Access rights indicate segment neither data nor readable code segment
                    OR Segment is data or nonconforming-code segment
                    AND both RPL and CPL > DPL)
                    THEN #GP(selector);
                    FI;
                ELSE IF Segment marked not present
                    THEN #NP(selector);
                    FI;
                    SegmentRegister  =  SegmentSelector(SRC) AND RPL;
                    SegmentRegister  =  SegmentDescriptor([SRC]);
                ELSE IF DS, ES, FS, or GS is loaded with a null selector:
                    SegmentRegister  =  NullSelector;
                    SegmentRegister(DescriptorValidBit)  =  0; (*hidden flag; not accessible by software*)
                FI;
            FI;
            IF (Real-Address or Virtual-8086 Mode)
            THEN
                SegmentRegister  =  SegmentSelector(SRC);
            FI;
            DEST  =  Offset(SRC);


@instruction<EOL><INDENT>def LEA(cpu, dest, src):<DEDENT>

dest.write(Operators.EXTRACT(src.address(), <NUM_LIT:0>, dest.size))<EOL>

Loads effective address.

Computes the effective address of the second operand (the source operand) and stores it in the first operand
(destination operand). The source operand is a memory address (offset part) specified with one of the processors
addressing modes; the destination operand is a general-purpose register. The address-size and operand-size
attributes affect the action performed by this instruction. The operand-size
attribute of the instruction is determined by the chosen register; the address-size attribute is determined by the
attribute of the code segment.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def MOV(cpu, dest, src, *rest):  <DEDENT>

dest.write(src.read())<EOL>

Move.

Copies the second operand (source operand) to the first operand (destination
operand). The source operand can be an immediate value, general-purpose
register, segment register, or memory location; the destination register
can be a general-purpose register, segment register, or memory location.
Both operands must be the same size, which can be a byte, a word, or a
doubleword.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.
:param rest: workaround for a capstone bug, should never be provided


@instruction<EOL><INDENT>def MOVBE(cpu, dest, src):<DEDENT>

size = dest.size<EOL>arg0 = dest.read()<EOL>temp = <NUM_LIT:0><EOL>for pos in range(<NUM_LIT:0>, size, <NUM_LIT:8>):<EOL><INDENT>temp = (temp << <NUM_LIT:8>) | (arg0 & <NUM_LIT>)<EOL>arg0 = arg0 >> <NUM_LIT:8><EOL><DEDENT>dest.write(arg0)<EOL>

Moves data after swapping bytes.

Performs a byte swap operation on the data copied from the second operand (source operand) and store the result
in the first operand (destination operand). The source operand can be a general-purpose register, or memory location; the destination register can be a general-purpose register, or a memory location; however, both operands can
not be registers, and only one operand can be a memory location. Both operands must be the same size, which can
be a word, a doubleword or quadword.
The MOVBE instruction is provided for swapping the bytes on a read from memory or on a write to memory; thus
providing support for converting little-endian values to big-endian format and vice versa.
In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits::

        TEMP = SRC
        IF ( OperandSize = 16)
        THEN
            DEST[7:0] = TEMP[15:8];
            DEST[15:8] = TEMP[7:0];
        ELSE IF ( OperandSize = 32)
            DEST[7:0] = TEMP[31:24];
            DEST[15:8] = TEMP[23:16];
            DEST[23:16] = TEMP[15:8];
            DEST[31:23] = TEMP[7:0];
        ELSE IF ( OperandSize = 64)
            DEST[7:0] = TEMP[63:56];
            DEST[15:8] = TEMP[55:48];
            DEST[23:16] = TEMP[47:40];
            DEST[31:24] = TEMP[39:32];
            DEST[39:32] = TEMP[31:24];
            DEST[47:40] = TEMP[23:16];
            DEST[55:48] = TEMP[15:8];
            DEST[63:56] = TEMP[7:0];
        FI;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


eflags_size = <NUM_LIT:32><EOL>val = cpu.AH & <NUM_LIT> | <NUM_LIT><EOL>cpu.EFLAGS = Operators.ZEXTEND(val, eflags_size)<EOL>

Stores AH into flags.

Loads the SF, ZF, AF, PF, and CF flags of the EFLAGS register with values
from the corresponding bits in the AH register (bits 7, 6, 4, 2, and 0,
respectively). Bits 1, 3, and 5 of register AH are ignored; the corresponding
reserved bits (1, 3, and 5) in the EFLAGS register remain as shown below::

        EFLAGS(SF:ZF:0:AF:0:PF:1:CF)  =  AH;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF) == False, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if above.

Sets the destination operand to 0 or 1 depending on the settings of the status flags (CF, SF, OF, ZF, and PF, 1, 0) in the
EFLAGS register. The destination operand points to a byte register or a byte in memory. The condition code suffix
(cc, 1, 0) indicates the condition being tested for::
        IF condition
        THEN
            DEST = 1;
        ELSE
            DEST = 0;
        FI;

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.CF == False, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if above or equal.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.CF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if below.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF), <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if below or equal.

:param cpu: current CPU.
:param dest: destination operand.


Sets if carry.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.ZF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if equal.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.ZF == False, cpu.SF == cpu.OF), <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if greater.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.SF == cpu.OF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if greater or equal.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.SF != cpu.OF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if less.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.ZF, cpu.SF != cpu.OF), <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if less or equal.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not above.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not above or equal.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not below.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.CF == False, cpu.ZF == False), <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if not below or equal.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not carry.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.ZF == False, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if not equal.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not greater.

:param cpu: current CPU.
:param dest: destination operand.


Sets if not greater or equal.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not less.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not less or equal.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.OF == False, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if not overflow.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.PF == False, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if not parity.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.SF == False, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if not sign.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if not zero.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.OF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if overflow.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.PF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if parity.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if parity even.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if parity odd.

:param cpu: current CPU.
:param dest: destination operand.


dest.write(Operators.ITEBV(dest.size, cpu.SF, <NUM_LIT:1>, <NUM_LIT:0>))<EOL>

Sets byte if sign.

:param cpu: current CPU.
:param dest: destination operand.


Sets byte if zero.

:param cpu: current CPU.
:param dest: destination operand.


@instruction<EOL><INDENT>def XCHG(cpu, dest, src):<DEDENT>

temp = dest.read()<EOL>dest.write(src.read())<EOL>src.write(temp)<EOL>

Exchanges register/memory with register.

Exchanges the contents of the destination (first) and source (second)
operands. The operands can be two general-purpose registers or a register
and a memory location. If a memory operand is referenced, the processor's
locking protocol is automatically implemented for the duration of the
exchange operation, regardless of the presence or absence of the LOCK
prefix or of the value of the IOPL.
This instruction is useful for implementing semaphores or similar data
structures for process synchronization.
The XCHG instruction can also be used instead of the BSWAP instruction
for 16-bit operands::

        TEMP  =  DEST
        DEST  =  SRC
        SRC  =  TEMP

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


cpu.STACK = cpu.FRAME<EOL>cpu.FRAME = cpu.pop(cpu.address_bit_size)<EOL>

High level procedure exit.

Releases the stack frame set up by an earlier ENTER instruction. The
LEAVE instruction copies the frame pointer (in the EBP register) into
the stack pointer register (ESP), which releases the stack space allocated
to the stack frame. The old frame pointer (the frame pointer for the calling
procedure that was saved by the ENTER instruction) is then popped from
the stack into the EBP register, restoring the calling procedure's stack
frame.
A RET instruction is commonly executed following a LEAVE instruction
to return program control to the calling procedure::

        IF Stackaddress_bit_size  =  32
        THEN
            ESP  =  EBP;
        ELSE (* Stackaddress_bit_size  =  16*)
            SP  =  BP;
        FI;
        IF OperandSize  =  32
        THEN
            EBP  =  Pop();
        ELSE (* OperandSize  =  16*)
            BP  =  Pop();
        FI;

:param cpu: current CPU.


dest.write(cpu.pop(dest.size))<EOL>

Pops a value from the stack.

Loads the value from the top of the stack to the location specified
with the destination operand and then increments the stack pointer.

:param cpu: current CPU.
:param dest: destination operand.


<EOL>size = src.size<EOL>v = src.read()<EOL>if size != <NUM_LIT:64> and size != cpu.address_bit_size // <NUM_LIT:2>:<EOL><INDENT>v = Operators.SEXTEND(v, size, cpu.address_bit_size)<EOL>size = cpu.address_bit_size<EOL><DEDENT>cpu.push(v, size)<EOL>

Pushes a value onto the stack.

Decrements the stack pointer and then stores the source operand on the top of the stack.

:param cpu: current CPU.
:param src: source operand.


mask = (<NUM_LIT> |<EOL><NUM_LIT> |<EOL><NUM_LIT> |<EOL><NUM_LIT> |<EOL><NUM_LIT> |<EOL><NUM_LIT> |<EOL><NUM_LIT>)<EOL>val = cpu.pop(<NUM_LIT:16>)<EOL>eflags_size = <NUM_LIT:32><EOL>cpu.EFLAGS = Operators.ZEXTEND(val & mask, eflags_size)<EOL>

Pops stack into EFLAGS register.

:param cpu: current CPU.


mask = <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT><EOL>cpu.EFLAGS = cpu.pop(<NUM_LIT:32>) & mask<EOL>


mask = <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT> | <NUM_LIT><EOL>cpu.EFLAGS = (cpu.EFLAGS & ~mask) | cpu.pop(<NUM_LIT:64>) & mask<EOL>


cpu.push(cpu.EFLAGS, <NUM_LIT:16>)<EOL>

Pushes FLAGS register onto the stack.

:param cpu: current CPU.


cpu.push(cpu.EFLAGS, <NUM_LIT:32>)<EOL>

Pushes EFLAGS register onto the stack.

:param cpu: current CPU.


cpu.push(cpu.RFLAGS, <NUM_LIT:64>)<EOL>

Pushes RFLAGS register onto the stack.

:param cpu: current CPU.


if op0.read() != <NUM_LIT>:<EOL><INDENT>logger.warning("<STR_LIT>")<EOL><DEDENT>raise Interruption(op0.read())<EOL>

Calls to interrupt procedure.

The INT n instruction generates a call to the interrupt or exception handler specified
with the destination operand. The INT n instruction is the  general mnemonic for executing
a software-generated call to an interrupt handler. The INTO instruction is a special
mnemonic for calling overflow exception (#OF), interrupt vector number 4. The overflow
interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler
if the OF flag is set to 1.

:param cpu: current CPU.
:param op0: destination operand.


raise Interruption(<NUM_LIT:3>)<EOL>


<EOL>proc = op0.read()<EOL>cpu.push(cpu.PC, cpu.address_bit_size)<EOL>cpu.PC = proc<EOL>

Procedure call.

Saves procedure linking information on the stack and branches to the called procedure specified using the target
operand. The target operand specifies the address of the first instruction in the called procedure. The operand can
be an immediate value, a general-purpose register, or a memory location.

:param cpu: current CPU.
:param op0: target operand.


<EOL>N = <NUM_LIT:0><EOL>if len(operands) > <NUM_LIT:0>:<EOL><INDENT>N = operands[<NUM_LIT:0>].read()<EOL><DEDENT>cpu.PC = cpu.pop(cpu.address_bit_size)<EOL>cpu.STACK += N<EOL>

Returns from procedure.

Transfers program control to a return address located on the top of
the stack. The address is usually placed on the stack by a CALL instruction,
and the return is made to the instruction that follows the CALL instruction.
The optional source operand specifies the number of stack bytes to be
released after the return address is popped; the default is none.

:param cpu: current CPU.
:param operands: variable operands list.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(cpu.CF == False, cpu.ZF == False), target.read(), cpu.PC)<EOL>

Jumps short if above.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF == False, target.read(), cpu.PC)<EOL>

Jumps short if above or equal.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF == True, target.read(), cpu.PC)<EOL>

Jumps short if below.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.OR(cpu.CF, cpu.ZF), target.read(), cpu.PC)<EOL>

Jumps short if below or equal.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF, target.read(), cpu.PC)<EOL>

Jumps short if carry.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CX == <NUM_LIT:0>, target.read(), cpu.PC)<EOL>

Jumps short if CX register is 0.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.ECX == <NUM_LIT:0>, target.read(), cpu.PC)<EOL>

Jumps short if ECX register is 0.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.RCX == <NUM_LIT:0>, target.read(), cpu.PC)<EOL>

Jumps short if RCX register is 0.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.ZF, target.read(), cpu.PC)<EOL>

Jumps short if equal.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(cpu.ZF == False, cpu.SF == cpu.OF), target.read(), cpu.PC)<EOL>

Jumps short if greater.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, (cpu.SF == cpu.OF), target.read(), cpu.PC)<EOL>

Jumps short if greater or equal.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, (cpu.SF != cpu.OF), target.read(), cpu.PC)<EOL>

Jumps short if less.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.OR(cpu.ZF, cpu.SF != cpu.OF), target.read(), cpu.PC)<EOL>

Jumps short if less or equal.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not above.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not above or equal.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not below.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not below or equal.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.CF, target.read(), cpu.PC)<EOL>

Jumps short if not carry.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.ZF, target.read(), cpu.PC)<EOL>

Jumps short if not equal.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not greater.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not greater or equal.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if not less.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(False == cpu.ZF, cpu.SF == cpu.OF), target.read(), cpu.PC)<EOL>

Jumps short if not less or equal.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.OF, target.read(), cpu.PC)<EOL>

Jumps short if not overflow.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.PF, target.read(), cpu.PC)<EOL>

Jumps short if not parity.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.SF, target.read(), cpu.PC)<EOL>

Jumps short if not sign.

:param cpu: current CPU.
:param target: destination operand.


cpu.JNE(target)<EOL>

Jumps short if not zero.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.OF, target.read(), cpu.PC)<EOL>

Jumps short if overflow.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.PF, target.read(), cpu.PC)<EOL>

Jumps short if parity.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if parity even.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if parity odd.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.SF, target.read(), cpu.PC)<EOL>

Jumps short if sign.

:param cpu: current CPU.
:param target: destination operand.


Jumps short if zero.

:param cpu: current CPU.
:param target: destination operand.


cpu.PC = target.read()<EOL>

Jump.

Transfers program control to a different point in the instruction stream without
recording return information. The destination (target) operand specifies the address
of the instruction being jumped to. This operand can be an immediate value, a general-purpose register, or a memory location.

:param cpu: current CPU.
:param target: destination operand.


logger.info("<STR_LIT>", cs_selector.read(), target.read())<EOL>cpu.CS = cs_selector.read()<EOL>cpu.PC = target.read()<EOL>

We are just going to ignore the CS selector for now.


counter_name = {<NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[cpu.address_bit_size]<EOL>counter = cpu.write_register(counter_name, cpu.read_register(counter_name) - <NUM_LIT:1>)<EOL>cpu.PC = Operators.ITEBV(cpu.address_bit_size, counter == <NUM_LIT:0>, (cpu.PC + dest.read()) & ((<NUM_LIT:1> << dest.size) - <NUM_LIT:1>), cpu.PC + cpu.instruction.size)<EOL>

Loops according to ECX counter.

Performs a loop operation using the ECX or CX register as a counter.
Each time the LOOP instruction is executed, the count register is decremented,
then checked for 0. If the count is 0, the loop is terminated and program
execution continues with the instruction following the LOOP instruction.
If the count is not zero, a near jump is performed to the destination
(target) operand, which is presumably the instruction at the beginning
of the loop. If the address-size attribute is 32 bits, the ECX register
is used as the count register; otherwise the CX register is used::

        IF address_bit_size  =  32
        THEN
            Count is ECX;
        ELSE (* address_bit_size  =  16 *)
            Count is CX;
        FI;
        Count  =  Count - 1;

        IF (Count  0)  =  1
        THEN
            EIP  =  EIP + SignExtend(DEST);
            IF OperandSize  =  16
            THEN
                EIP  =  EIP AND 0000FFFFH;
            FI;
        ELSE
            Terminate loop and continue program execution at EIP;
        FI;

:param cpu: current CPU.
:param dest: destination operand.


counter_name = {<NUM_LIT:16>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[cpu.address_bit_size]<EOL>counter = cpu.write_register(counter_name, cpu.read_register(counter_name) - <NUM_LIT:1>)<EOL>cpu.PC = Operators.ITEBV(cpu.address_bit_size, counter != <NUM_LIT:0>, (cpu.PC + target.read()) & ((<NUM_LIT:1> << target.size) - <NUM_LIT:1>), cpu.PC + cpu.instruction.size)<EOL>

Loops if ECX counter is nonzero.

:param cpu: current CPU.
:param target: destination operand.


@instruction<EOL><INDENT>def RCL(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>count = src.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND((count & countMask) % (src.size + <NUM_LIT:1>), OperandSize)<EOL>value = dest.read()<EOL>if isinstance(tempCount, int) and tempCount == <NUM_LIT:0>:<EOL><INDENT>new_val = value<EOL>dest.write(new_val)<EOL><DEDENT>else:<EOL><INDENT>carry = Operators.ITEBV(OperandSize, cpu.CF, <NUM_LIT:1>, <NUM_LIT:0>)<EOL>right = value >> (OperandSize - tempCount)<EOL>new_val = (value << tempCount) | (carry << (tempCount - <NUM_LIT:1>)) | (right >> <NUM_LIT:1>)<EOL>dest.write(new_val)<EOL>def sf(v, size):<EOL><INDENT>return (v & (<NUM_LIT:1> << (size - <NUM_LIT:1>))) != <NUM_LIT:0><EOL><DEDENT>cpu.CF = sf(value << (tempCount - <NUM_LIT:1>), OperandSize)<EOL>cpu.OF = Operators.ITE(tempCount == <NUM_LIT:1>,<EOL>sf(new_val, OperandSize) != cpu.CF,<EOL>cpu.OF)<EOL><DEDENT>

Rotates through carry left.

Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the
second operand (count operand) and stores the result in the destination operand. The destination operand can be
a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in
the CL register. In legacy and compatibility mode, the processor restricts the count to a number between 0 and 31
by masking all the bits in the count operand except the 5 least-significant bits.

The RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.