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": {}
  }
 ]
}