Instructions for Lab 6
Instruction Execution
We have now built a hardware machine but we still can't execute
machine programs. We are going to write the code that performs the
actions required by each machine instruction. The actions needed to
execute each instruction are all encapsulated in an instruction
visitor:
public class ExecIns implements InsVisitor {
...
}
Clearly the visitor needs access to the machine registers, memory,
ALU, etc to perform its job. In other words, you will need instance
variables for the machine components. The constructor takes the entire
machine as an argument and initializes the instance variables:
public ExecIns (MachineI m) {
...
}
Our job now is to write each method in the InsVisitor interface so
that it updates the machine's state to reflect the effect of executing
the instruction. Let's look at some examples.
First, a halt instruction is straightforward:
public void visitHaltIns (HaltIns i) throws HaltE {
throw new HaltE();
}
A slightly more interesting example is the clear instruction. An
instruction ``clear X'' stores a 0 in the location X. This can be
easily implemented as follows:
public void visitClearIns (ClearIns i) throws MachineE {
Word w = new Data(0);
mem.store(i.getAddress(), w);
}
To implement the remaining operations, we will need to describe the
meaning of the instructions in some detail:
- load X: copies the contents of location X into the ACC register.
- store X: copies the contents of the ACC register into location X.
- clear X: writes a 0 in location X.
- add X: adds the contents of the ACC register with the contents of
location X; stores the result in the ACC register.
- increment X: increments the contents of location X; stores the
result in location X.
- subtract X: subtracts the contents of location X from the contents
of the ACC register; stores the result in the ACC register.
- decrement X: decrements the contents of location X;
stores the result in location X.
- compare X: compares the contents of the location X with
the contents of the ACC register and sets the ALU flags
accordingly. For example, if the contents of X are greater than the
contents of the ACC register, the GT flag should be set.
- jump X: stores X in the PC.
- jumpgt X: stores X in the PC if the GT flag is set.
- jumpeq X: stores X in the PC if the EQ flag is set.
- jumplt X: stores X in the PC if the LT flag is set.
- jumpneq X: stores X in the PC if the EQ flag is not set.
- in X: inputs an integer value and stores it in location X.
- out X: outputs the contents of location X.
- halt: stops program execution.
The realization of the methods should now be routine.
Tracing
Our design gives us added flexibility. Consider that we want to trace
the execution of the program by printing every instruction that's
about to be executed. We will print the information on the machine's
output stream (called here outWriter) which we get can using the
method getWriter() in the ioUnit class.
We can achieve this without touching any previously written code by
simply writing a new visitor that behaves like ExecIns above except
that it also prints every instruction before executing it. Here are
the first few lines of such a visitor:
public class ExecTraceIns extends ExecIns {
public ExecTraceIns (MachineI m) {
super(m);
}
public void visitHaltIns (HaltIns i) throws HaltE {
outWriter.println(i.toString());
super.visitHaltIns(i);
}
public void visitAddIns (AddIns i) throws MachineE {
outWriter.println(i.toString());
super.visitAddIns(i);
}
public void visitClearIns (ClearIns i) throws MachineE {
outWriter.println(i.toString());
super.visitClearIns(i);
}
...
}
A Little Debugger
We can further refine the previous visitor to print some debugging
information about the machine status at every step. The first few
lines of such a visitor follow:
public class DebugIns extends ExecTraceIns {
public DebugIns (MachineI m) {
super(m);
}
public void visitHaltIns (HaltIns i) throws HaltE {
super.visitHaltIns(i);
}
public void visitAddIns (AddIns i) throws MachineE {
super.visitAddIns(i);
printStatus();
}
public void visitClearIns (ClearIns i) throws MachineE {
super.visitClearIns(i);
printStatus();
}
...
// assuming the visitor has instance variables proc and alu
private void printStatus () {
outWriter.print("\tPC=" + proc.fetchPC());
outWriter.print("\tACC=" + proc.fetchACC());
outWriter.print("\tGT/EQ/LT=" + alu.fetchGT() + "/" +
alu.fetchEQ() + "/" + alu.fetchLT());
outWriter.print("\n\n");
outWriter.flush();
}
To Do
Finish the implementation of ExecIns, ExecTraceIns, and DebugIns
above. Here is a
file to test your code.
Visited
times since December 15, 1997 (or the last crash).
sabry@cs.uoregon.edu