Example #1
0
  def pass2(self):
    '''
    Second pass of the assembly process.

    Once the asm source code has been assembled into the intermediate
    form (by ``assemble()`` or ``assemble_file()``) this method converts
    it into binary strings.

    :rtype: Mapping of addresses to strings (binary data) this data
       structure is the end result of the assembly process, just before
       emitting the strings in e.g. Intel HEX format for burning to a
       chip.
    '''
    log.debug('Pass 2 #############################################')
    accumulator = self.accumulator
    for addr in sorted(self.data):
      instruction = self.data[addr]
      op, args = instruction[0], instruction[1:]

      # Adjust addresses for relative ops.
      if op in ('rcall', 'rjmp', 'brne', 'breq', 'brlo', 'brcc', 'brsh'):
        args = self._adjust(op, args, ibv(int(addr, 16)))

      # see instruction in Amtel manual.
      elif op in ('clr', 'lsl'):
        args = args + args

      opf = self.ops.get(op, lambda *args: (0, args))
      n, data = opf(*args)

      if n <= 0:
        bindata = data
      elif n == 16:
        bindata = pack('H', data)
      else:
        bindata = pack('2H', data[32:16], data[16:])

      # debug logging
      if op in ('db', 'dw'):
        log.debug(' '.join('%s' * 6),
                  addr, 10 * ' ', op, len(data), 'bytes:', repr(data))
      else:
        try:
          fdata = '%-10x' % (data,)
        except TypeError:
          log.debug(' '.join('%s' * 5),
                  addr, 10 * '.', op, tuple(map(hex, args)), repr(data))
        else:
          log.debug(' '.join('%s' * 5),
                  addr, fdata, op, tuple(map(hex, args)), repr(bindata))

      accumulator[addr] = bindata

    return accumulator
Example #2
0
  def org(self, address):
    '''
    Set the current output address of the assembly process to
    ``address``.  If ``address`` isn't an ``intbv`` it is converted to
    one.

    :param address: Location in program.
    :type address: ``intbv``, ``int``, or symbolic label.
    :rtype: ``None``
    '''
    address = ibv(address)
    log.debug('setting org to %#06x', address)
    update(self.here, address)
Example #3
0
  def define(self, **defs):
    '''
    Update one or more names in the execution namespace.  The main
    difference between using this function and simply setting a variable
    in your asm code is that this function automatically converts
    integer value(s) into ``intbv`` object(s).

    :param defs: ``<name>=<value>`` pairs
    :rtype: ``None``
    '''
    for k, v in defs.iteritems():
      if isinstance(v, int):
        defs[k] = v = ibv(v)
      log.debug('defining %s = %#x', k, v)
    self.context.update(defs)
Example #4
0
 def _adjust(self, op, args, addr):
   return (ibv(args[0] - addr - 1),)