Assembler framework

The core of the assembler framework is an abstract class "Assembler". You can get the Assembler class from the asm-sim-framework svn repository. You may develop your own assembler by create a new class that inherits the Assembler class and realize the abstract methods of the Assembler class. The AssembleCode method in the Assembler class contains a process that will help you parse the code and generate the machine code. The current Assembler class supports the following features:

Features

Take a look of the following sample assembly code written in the old FlexGermanica ISA:
.text
        la  $1, table0    // load the address of a label table0 (pseudo instruction)
        lw  $2, $1        // $2 <= 0x000C0FFEE
        lw  $3, table0    // load the value at label table0 (pseudo instruction), $3 <= 0x000C0FFEE
        lw  $4, 3(table0) // $4 <= table1
        lw  $5, 1($4)     // $5 <= 0x1DEADBEEF
        sw  $5, 1($1)     // 0x001COFFEE is overwritten to 0x1DEADBEEF
        li  $6, 0xC0FFEE  // load immediate (pseudo instruction), $6 <= 0xC0FFEE

.data
   table0:
        .word 0x000C0FFEE
        .word 0x001C0FFEE
        .word 0x002C0FFEE
        .word table1
   table1:
        .word 0x0DEADBEEF
        .word 0x1DEADBEEF
        .word 0x2DEADBEEF
        .word 0x3DEADBEEF
        .word 0x0DEADBEEF, 0x1DEADBEEF, 0x2DEADBEEF
        .fill 10 0x0

Detail Description of Classes

In the following paragraphs, we will provide a detail description of classes in our assembler framework. We will first start by the Assembler class, which is the core of assembler framework. The assembler framework also has an Instruction class, Operand class, a Memory class, and a MemoryEntry class to help the Assembler class complete the assemler functions. In the following paragraphs, we will describe these classes in detail.

Assembler Class

The Assembler class has the following fields:

Field Summary
public BufferedReader sourceFile

The file reader of the input source file. You need to intialize it before processing the source code.
public BufferedWriter out_code

The file writer for machine code output (*_i.coe). You need to initialize it before generating any code output.
public BufferedWriter out_data

The file writer for data code output (*_d.coe). You need to initialize it before generating any data output.
public String[] keywords

The array stores the keywords used by the Assembler. You may override it in your class to extend the assembly language with more keywords.
public Instruction instructions

An array of Instruction objects that stores the parsed instructions.
public Memory memory

The object stores the parsed data words.
public int instructionCount

The number of scanned instructions.
public int currentCodeSection

The current code section. By default, 0 stands for text section, and 1 for data section.
public int programCounter

The current program counter. You may need it while processing labels.
public int dataMemoryAddress

The current data memory address. You may need it while processing labels.
public int currentSourceCodeline

How many source code lines has been scanned. You may not need it since the framework only uses for generating error messages.

The Assembler class has two different constructors:

Constructor Summary
Assembler()

Construct an Assembler object without any initialization.
Assembler(String[] args)

Construct an Assembler object with the file I/O handlers initialized.

The Assembler class has following methods:

Method Summary
public String getNextInputLine()

Get the next non-comment or non-empty line from the source code file, and return the scanned line with a String. All contents after "//" will be ignored and will not be contained in the returned String. Once the source code reaches an EOF, the method will return a "null".
boolean isKeyword(String sourceCodeLine)

Examine if the input line from source code contains a keyword.
String extractKeyword(String sourceCodeLine)

Extract the keyword from the input string.
boolean isLabel(String sourceCode)

Examine if the input line from source code contains a label.
String extractLabel(String sourceCodeLine)

Extract the label from the input string.
Instruction processInstruction(String sourceCode)

Parse the input source code into an Instruction object.
void processData(String sourceCode)

Parse the source code from the data section into the memory object of Assembler.
public static String getOperandType(String operand)

Examine if the input operand string is a meaningful term. The returned String will be "register" if the operand starts with "$". The returned String will be "immediate" if the operand starts with "0x". The returned String will be "label" if the operand cannot be categorize into the last two categories.
public void outputErrorMessage(String errorMessage)

Output the error message and show the incorrect source code line.
public void AssembleCode(String arg[])

The most important method in Assembler class. This function controls the flow of Assembler. You may not need to change it. However, you may also override it if you have a better algorithm than our current two-parse algorithm.
void processAdditionalKeywords(String sourceCode)

You may override to process additional keywords.
abstract void processLabel(String sourceCode)

You have to implement it to process the labels. You may also need to implement a symbol table to maintain the labels and their real addresses.
abstract void replaceInstructionLabel(Instruction instruction)

Replace the operands in the form of labels with immediate values. The method will be called before generating the machine code for an instruction in the AssembleCode method.
abstract String generateCode(Instruction instruction)

You have to implement it for generating the machine code from an Instruction object.
abstract void updateProgramCounter(Instruction instruction)

You have to implement it for updating the programCounter. If your algorithm does not require the variable, you may implement it as an empty method.
abstract void initialization()

The method is called before the source code is scanned or generated. You have to implement it to initialize some variables, such as file descriptors or local variables, in your class.
abstract void replaceMemoryLabel()

The method is called before the data memory is dumped to a $prefix_d.coe file. It will replace the data written in labels with immediate values.

Instruction Class

For each instruction in the text section, the assembler framework will parse them into an array of Instruction objects. The Instruction class has the following fields:

Field Summary
public String operator

A string stores the operator of the instruction. Take the code sw $5, 1($1) as an example, the operator will be the string "sw".
public Operand operands

An array of Operand objects stores the arguments of the instruction.

The Instruction class has two different constructors:

Constructor Summary
Instruction(String sourceCodeLine)

Construct an Instruction object using the scanned source code.
Instruction(String operator, Operand operands[])

Construct an Instruction object using the assigned operator and operands.

The Instruction class has following methods:

Method Summary
public void print()

Print the operartor and operands of the current Instruction object.

Operand Class

The Operand class has the following fields:

Field Summary
public String name

A string stores the name of a operand.
public int offset

A offset of this operand.

The Operand class has two different constructors:

Constructor Summary
Operand()

Construct an Operand object with their name initialized as "", and offset initialized as 0
Operand(String i_name, int i_offset)

Construct an Operand object with their name initialized as i_name, and offset initialized as i_offset

The Operand class has the following method:

Method Summary
public String getOperandType(String operand)

Examine if the input operand string is a meaningful term. The returned String will be "register" if the operand starts with "$". The returned String will be "immediate" if the operand starts with "0x". The returned String will be "label" if the operand cannot be categorize into the last two categories.
public int extractRegisterNumber()

If the operand is a register, this method will return an integer value of the register number. Otherwise, the method will return -1.
public long extractImmediate()

If the operand is an immediate value, this method will return an integer value of the immediate value. Otherwise, the method will return Integer.MIN_VALUE.

Memory Class

The Memory class has the following fields:

Field Summary
int size

Number of elements in the Memory class object.
public MemoryEntry[] entries

An array stores the data in the memory.

The Memory class has two different constructors:

Constructor Summary
Memory()

Construct an Memory object with the number of entries initialized to 1024.
Memory(int n)

Construct an Memory object with the number of entries initialized to n.

The Memory class has the following method:

Method Summary
public void add(String data,int address)

Add the data into the Memory object and bookkeeping its data memory address.
public void find(int address)

Find the data stored in input address.
public void print()

Print the content of current Memory object.
public void dump()

Dump the content of current Memory object as the form of 34-bit machine code.
public int leng()

Return the size of current entries.

MemoryEntry Class

The MemoryEntry class has the following fields:

Field Summary
String data

A string stores the data word in an memory entry.
int address

The data memory address of the object.