code: def requires(self, i=0, end_=None):
          
          if i < 0:
              i = 0
          end_ = len(self) if end_ is None or end_ > len(self) else end_
          regs = {'a', 'b', 'c', 'd', 'e', 'f', 'h', 'l', 'i', 'ixh', 'ixl', 'iyh', 'iyl', 'sp'}
          result = []
  
          for ii in range(i, end_):
              for r in self.mem[ii].requires:
                  r = r.lower()
                  if r in regs:
                      result.append(r)
                      regs.remove(r)
  
              for r in self.mem[ii].destroys:
                  r = r.lower()
                  if r in regs:
                      regs.remove(r)
  
              if not regs:
                  break
  
          return result
docs: Returns a list of registers and variables this block requires.
          By default checks from the beginning (i = 0).
          :param i: initial position of the block to examine
          :param end_: final position to examine
          :returns: registers safe to write