Mercurial > hg > ede
view utils/assembler.ipynb @ 1:82e82dda442b
alpha version of assembler 'finished'
some more documentation and test files added
author | james <jb302@eecs.qmul.ac.uk> |
---|---|
date | Fri, 06 Dec 2013 23:39:54 +0000 |
parents | |
children |
line wrap: on
line source
{ "metadata": { "name": "assembler" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "code", "collapsed": false, "input": [ "#!/usr/bin/env python2\n", "# assembler.py\n", "import struct\n", "from language import *" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "# take source file and return preprocessed assembly code and label index\n", "def first_pass(f):\n", " f.seek(0)\n", " asm = []\n", " labels = {}\n", " # read file into list, remove blank line\n", " source_code = filter(lambda l: l != '\\n', f.readlines())\n", " \n", " pc = 0\n", " # <line> ::= [<statement>] [\";\"<comment>] <EOL>\n", " for line in source_code:\n", " # remove EOL\n", " line = line.strip()\n", " # remove comments\n", " for i in range(len(line)):\n", " if line[i] == ';':\n", " line = line[:i]\n", " break\n", " line = line.lower()\n", " \n", " # <statement> ::= [ <label> \":\"] <mnemonic> [<arguments>]\n", " # | <label> \":\"\n", " # | \"end\"\n", " # skip empty statements\n", " statement = line.split()\n", " # skip empty statements\n", " if not statement: continue\n", " # if needed update label index and remove label \n", " if statement[0][-1:] == ':':\n", " labels.update({(statement[0][:-1]):pc})\n", " del statement[0]\n", " \n", " # and again skip empty statements\n", " if not statement: continue\n", " \n", " mnemonic = statement[0]\n", " arguments = ''.join(statement[1:]).split(',')\n", " \n", " symbols, constants = tokenize(arguments)\n", " asm.append([mnemonic, symbols, constants])\n", " \n", " pc = pc + len(constants) + 1\n", "\n", " return asm, labels" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "def second_pass(f, asm, labels):\n", " pc = 0\n", " offset = 0\n", " \n", " for line in asm:\n", " mne, sym, const = line\n", " f.seek(pc)\n", " \n", " # update labels\n", " i = 0\n", " for s in sym:\n", " if s in labels:\n", " # replace labels with hex strings\n", " label = sym[i]\n", " a = labels[s]\n", " # if label address less than pc\n", " if a < pc:\n", " sym[i] = hex(a)\n", " else:\n", " # deal with offset due to labels of unknow length\n", " sym[i] = hex(a + offset)\n", " # retokenize\n", " sym, const = tokenize(sym)\n", " \n", " i = i + 1\n", " offset = offset + len(const)\n", " \n", " # assemble to file\n", " # make symbols hashable\n", " sym = tuple(sym)\n", " try:\n", " f.write(struct.pack('>B', iset[mne][sym]))\n", " except:\n", " print 'syntax error: %s %s' % (mne, sym)\n", " return 'symbol_error'\n", " \n", " f.write(const) \n", " pc = pc + len(const) + 1\n", " \n", " f.seek(0) \n", " return f\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "f = open('testb.asm', 'r')\n", "b = open('test.bin', 'wb')\n", "asm, labels = first_pass(f)\n", "print labels\n", "b = second_pass(b, asm, labels)\n", "b.close()\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'label_4': 4, 'label_1': 0, 'label_2': 2, 'label_3': 3}\n" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 171 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }