def _name_or_addr(self, address): if isinstance(address, str): assert len(address) == 1, repr(address) address = ord(address) if isinstance(address, int): name = '%#06x' % address address = int2addr(address) else: assert isinstance(address, intbv), repr(address) name = self._name_of_address_thunk(address) return name, address
def __init__(self, initial_context=None): #: This is the execution context for your assembly file. It is used #: as the namespace for ``exec`` or ``execfile`` for parsing and #: running your code. #: #: Because it's a ``defaultdict`` and the default factory function #: returns ``intbv`` objects **any** name (identifier) that you use #: in your code that is not previously defined will automatically #: generate a new variable binding. #: #: That is how labels work: you simply use a label and it gets its #: own ``intbv`` object. Then when you use the ``label()`` #: *directive* on that label the ``intbv`` gets updated with the #: actual current output address, and that value will be used to #: assemble the proper bit patterns in ``pass2()``. self.context = defaultdict(lambda: int2addr(0)) self.context.update(self._instruction_namespace()) self.context.update(self._directives()) self.context.update((f.__name__, f) for f in ( low, high, ) ) self.context['range'] = xrange if initial_context is not None: self.context.update(initial_context) #: Current output address of the assembly process. self.here = int2addr(0) #: Internal intermediate data structure. This holds the output of #: the methods in the ``InstructionsMixin`` used to create the byte #: strings in ``pass2()``. self.data = {} #: Internal output data structure. This holds the byte strings #: created in ``pass2()``. self.accumulator = {}