code: def emulate(self, context=None, start=None, end=None, arch_mode=None, hooks=None, max_instrs=None, print_asm=False):
          
          if arch_mode is not None:
              # Reload modules.
              self._load(arch_mode=arch_mode)
  
          context = context if context else {}
  
          start_addr = start if start else self.binary.ea_start
          end_addr = end if end else self.binary.ea_end
  
          hooks = hooks if hooks else {}
  
          # Load registers
          for reg, val in context.get('registers', {}).items():
              self.ir_emulator.registers[reg] = val
  
          # Load memory
          # TODO Memory content should be encoded as hex strings so each
          # entry can be of different sizes.
          for addr, val in context.get('memory', {}).items():
              self.ir_emulator.memory.write(addr, 4, val)
  
          # Execute the code.
          self.emulator.emulate(start_addr, end_addr, hooks, max_instrs, print_asm)
  
          context_out = {
              'registers': {},
              'memory': {}
          }
  
          # save registers
          for reg, val in self.ir_emulator.registers.items():
              context_out['registers'][reg] = val
  
          return context_out
docs: Emulate native code.
  
          Args:
              context (dict): Processor context (register and/or memory).
              start (int): Start address.
              end (int): End address.
              arch_mode (int): Architecture mode.
              hooks (dict): Hooks by address.
              max_instrs (int): Maximum number of instructions to execute.
              print_asm (bool): Print asm.
  
          Returns:
              dict: Processor context.