# 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/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):


from functools import partialmethod as P
from unittest.mock import MagicMock
from ..CPU import CPU32
from ..util import Instruction, to_int, to_signed, byteorder
    from ..debug import debug_operand, debug_register_operand
    import logging
        
        return True

    def rm_m(vm: CPU32) -> bool:
        old_eip = vm.eip

        sz = vm.operand_size
        RM, R = vm.process_ModRM()

        if R[1] == 4:  # this is jmp r/m
            type, loc = RM

            tmpEIP = (type).get(loc, vm.address_size) 
                      
            vm.eip = tmpEIP & MAXVALS[vm.address_size]

            assert vm.eip < vm.mem.size

            if __debug__:
                logger.debug('jmp rm%d 0x%x', sz * 8, vm.eip)

            return True
        elif R[1] == 5:  # this is jmp m
            segment_selector_address = to_int(vm.mem.get(vm.eip, vm.address_size), True)
            vm.eip += vm.address_size
            offset_address = to_int(vm.mem.get(vm.eip, vm.address_size), True)
            vm.eip += vm.address_size

            sz = 4 if vm.operand_size == 4 else 2


# 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/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/instructions/control.py
from functools import partialmethod as P
from unittest.mock import MagicMock
from ..CPU import CPU32
from ..util import Instruction, to_int, to_signed, byteorder
    from ..debug import debug_operand, debug_register_operand
    import logging

        
        return True

    def rm_m(vm: CPU32) -> bool:
        old_eip = vm.eip

        sz = vm.operand_size
        RM, R = vm.process_ModRM()

        if R[1] == 4:  # this is jmp r/m
            type, loc = RM

            tmpEIP = (type).get(loc, vm.address_size) 
                      
            vm.eip = tmpEIP & MAXVALS[vm.address_size]

            assert vm.eip < vm.mem.size

            if __debug__:
                logger.debug('jmp rm%d 0x%x', sz * 8, vm.eip)

            return True
        elif R[1] == 5:  # this is jmp m
            segment_selector_address = to_int(vm.mem.get(vm.eip, vm.address_size), True)
            vm.eip += vm.address_size
            offset_address = to_int(vm.mem.get(vm.eip, vm.address_size), True)
            vm.eip += vm.address_size

            sz = 4 if vm.operand_size == 4 else 2


            segment_selector = to_int(vm.mem.get(segment_selector_address, 2), True)