# Path: VM/util.py
# def to_int(data: bytes, signed=False):
# def to_signed(num: int, bytes: int) -> int:
# def is_signed_out_of_range(num: int, size: int) -> bool:
#     def __init__(cls, name, bases, dct):
#     def __init__(cls, name, bases, dct):
#     def load_instruction(cls, instruction, opcode, implementation):
#     def __init__(self):
# class MissingOpcodeError(RuntimeError):
# class InstructionMeta(type):
# class CPUMeta(type):
# class Instruction(metaclass=InstructionMeta):
# class CPU(metaclass=CPUMeta):
# 
# Path: VM/misc.py
# def sign_extend(num: int, nbytes: int) -> int:
#     # TODO: this is basically converting an unsigned number to signed. Maybe rename the function?
#     """
#     See: https://stackoverflow.com/a/32031543/4354477
#     :param num: The integer to sign-extend
#     :param nbytes: The number of bytes _in that integer_.
#     :return:
#     """
#     if num < 0:
#         return num
#     
#     sign_bit = 1 << (nbytes * 8 - 1)
#     return (num & (sign_bit - 1)) - (num & sign_bit)
# 
# def parity(num: int) -> int:
#     """
#     Calculate the parity of the least significant byte of a number.
#     See: https://graphics.stanford.edu/~seander/bithacks.html#ParityWith64Bits
#     :param num: The byte to calculate the parity of.
#     :return:
#     """
# 
#     return ((((num & 0xFF) * 0x0101010101010101) & 0x8040201008040201) % 0x1FF) & 1
# 
# Path: VM/CPU.py
# class CPU32(CPU):
#     __slots__ = ('reg', 'sreg', 'mem', 'fpu', 'eip', 'opcode',
#                  'modes', 'default_mode', 'current_mode',
#                  'sizes', 'operand_size', 'address_size', 'stack_address_size',
#                  'code_segment_end', 'running', 'fmt'
#                  )
# 
#     def __init__(self, memsize: int):
#         super().__init__()
# 
#         self.reg = Reg32()
#         self.sreg = Sreg()
# 
#         self.fpu = FPU()
#         self.mem = Memory(memsize, self.sreg)  # stack grows downward, user memory - upward
# 
#         self.eip = 0
#         self.opcode = 0
# 
#         self.modes = (32, 16)  # number of bits
#         self.sizes = (4, 2)  # number of bytes
#         self.default_mode = 0  # 0 == 32-bit mode; 1 == 16-bit mode
#         self.current_mode = self.default_mode
# 
#         self.operand_size = self.sizes[self.current_mode]
#         self.address_size = self.sizes[self.current_mode]
#         self.stack_address_size = self.sizes[self.current_mode]
# 
#         self.code_segment_end = 0
#         self.stack_init()
#         self.running = True
#         self.fmt = '\t[%#08x]\t%02x'
#         
#     def stack_init(self):
#         self.reg.esp = self.mem.size - 1
#         self.reg.ebp = self.mem.size - 1
# 
#     def stack_push(self, value: int) -> None:
#         old_esp = self.reg.get(esp, self.stack_address_size)
#         new_esp = old_esp - self.operand_size
# 
#         if new_esp < self.mem.program_break:
#             raise RuntimeError(f"The stack cannot grow larger than {self.mem.program_break}")
# 
#         self.mem.set(new_esp, self.operand_size, value)
#         self.reg.set(esp, self.stack_address_size, new_esp)
# 
#     def stack_pop(self, size: int) -> int:
#         # TODO: check if stack is empty?
#         old_esp = self.reg.get(esp, self.stack_address_size)
# 
#         data = self.mem.get(old_esp, size)
#         new_esp = old_esp + size
#         self.reg.set(esp, self.stack_address_size, new_esp)
# 
#         return data


from ..util import Instruction, to_int, byteorder, SegmentRegs
from ..misc import sign_extend, parity
from ..CPU import CPU32
from functools import partialmethod as P
    from ..debug import debug_operand, debug_register_operand
    import logging
            logger.debug('push 0x%x', data)

        return True

    def sreg(vm: CPU32, reg) -> bool:
        """
        Push a segment register onto the stack.

        :param reg: the name of the register to be pushed.
        """

        # TODO: implement this
        return False


####################
# PUSHF / PUSHFD
####################
class PUSHF(Instruction):
    """
    Decrements the stack pointer by 4 (if the current operand-size attribute is 32) and pushes the entire contents of
    the EFLAGS register onto the stack, or decrements the stack pointer by 2 (if the operand-size attribute is 16) and
    pushes the lower 16 bits of the EFLAGS register (that is, the FLAGS register) onto the stack.
    These instructions reverse the operation of the POPF/POPFD instructions.
    """
    def __init__(self):
        self.opcodes = {
            0x9C: self.pushf
        }


# Path: VM/util.py
# def to_int(data: bytes, signed=False):
# def to_signed(num: int, bytes: int) -> int:
# def is_signed_out_of_range(num: int, size: int) -> bool:
#     def __init__(cls, name, bases, dct):
#     def __init__(cls, name, bases, dct):
#     def load_instruction(cls, instruction, opcode, implementation):
#     def __init__(self):
# class MissingOpcodeError(RuntimeError):
# class InstructionMeta(type):
# class CPUMeta(type):
# class Instruction(metaclass=InstructionMeta):
# class CPU(metaclass=CPUMeta):
# 
# Path: VM/misc.py
# def sign_extend(num: int, nbytes: int) -> int:
#     # TODO: this is basically converting an unsigned number to signed. Maybe rename the function?
#     """
#     See: https://stackoverflow.com/a/32031543/4354477
#     :param num: The integer to sign-extend
#     :param nbytes: The number of bytes _in that integer_.
#     :return:
#     """
#     if num < 0:
#         return num
#     
#     sign_bit = 1 << (nbytes * 8 - 1)
#     return (num & (sign_bit - 1)) - (num & sign_bit)
# 
# def parity(num: int) -> int:
#     """
#     Calculate the parity of the least significant byte of a number.
#     See: https://graphics.stanford.edu/~seander/bithacks.html#ParityWith64Bits
#     :param num: The byte to calculate the parity of.
#     :return:
#     """
# 
#     return ((((num & 0xFF) * 0x0101010101010101) & 0x8040201008040201) % 0x1FF) & 1
# 
# Path: VM/CPU.py
# class CPU32(CPU):
#     __slots__ = ('reg', 'sreg', 'mem', 'fpu', 'eip', 'opcode',
#                  'modes', 'default_mode', 'current_mode',
#                  'sizes', 'operand_size', 'address_size', 'stack_address_size',
#                  'code_segment_end', 'running', 'fmt'
#                  )
# 
#     def __init__(self, memsize: int):
#         super().__init__()
# 
#         self.reg = Reg32()
#         self.sreg = Sreg()
# 
#         self.fpu = FPU()
#         self.mem = Memory(memsize, self.sreg)  # stack grows downward, user memory - upward
# 
#         self.eip = 0
#         self.opcode = 0
# 
#         self.modes = (32, 16)  # number of bits
#         self.sizes = (4, 2)  # number of bytes
#         self.default_mode = 0  # 0 == 32-bit mode; 1 == 16-bit mode
#         self.current_mode = self.default_mode
# 
#         self.operand_size = self.sizes[self.current_mode]
#         self.address_size = self.sizes[self.current_mode]
#         self.stack_address_size = self.sizes[self.current_mode]
# 
#         self.code_segment_end = 0
#         self.stack_init()
#         self.running = True
#         self.fmt = '\t[%#08x]\t%02x'
#         
#     def stack_init(self):
#         self.reg.esp = self.mem.size - 1
#         self.reg.ebp = self.mem.size - 1
# 
#     def stack_push(self, value: int) -> None:
#         old_esp = self.reg.get(esp, self.stack_address_size)
#         new_esp = old_esp - self.operand_size
# 
#         if new_esp < self.mem.program_break:
#             raise RuntimeError(f"The stack cannot grow larger than {self.mem.program_break}")
# 
#         self.mem.set(new_esp, self.operand_size, value)
#         self.reg.set(esp, self.stack_address_size, new_esp)
# 
#     def stack_pop(self, size: int) -> int:
#         # TODO: check if stack is empty?
#         old_esp = self.reg.get(esp, self.stack_address_size)
# 
#         data = self.mem.get(old_esp, size)
#         new_esp = old_esp + size
#         self.reg.set(esp, self.stack_address_size, new_esp)
# 
#         return data


# Path: VM/instructions/memory.py
from ..util import Instruction, to_int, byteorder, SegmentRegs
from ..misc import sign_extend, parity
from ..CPU import CPU32
from functools import partialmethod as P
    from ..debug import debug_operand, debug_register_operand
    import logging

            logger.debug('push 0x%x', data)

        return True

    def sreg(vm: CPU32, reg) -> bool:
        """
        Push a segment register onto the stack.

        :param reg: the name of the register to be pushed.
        """

        # TODO: implement this
        return False


####################
# PUSHF / PUSHFD
####################
class PUSHF(Instruction):
    """
    Decrements the stack pointer by 4 (if the current operand-size attribute is 32) and pushes the entire contents of
    the EFLAGS register onto the stack, or decrements the stack pointer by 2 (if the operand-size attribute is 16) and
    pushes the lower 16 bits of the EFLAGS register (that is, the FLAGS register) onto the stack.
    These instructions reverse the operation of the POPF/POPFD instructions.
    """
    def __init__(self):
        self.opcodes = {
            0x9C: self.pushf
        }


    def pushf(vm: CPU32) -> True: