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
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)
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)
def _adjust(self, op, args, addr): return (ibv(args[0] - addr - 1),)