Being able to read a trace of code execution in assembly language is very helpful in debugging. To this end, the TTP assembler includes an “analysis” tab/sheet so a developer can trace code execution.
Regardless of which method is used, the following steps must be performed prior to tracing code execution.
Put the source code (ttpasm) in the “source” sheet in the assembler. Make sure there are no tab characters if the code is copied-and-pasted.
Fix all the assemble time errors.
Use “File | Download” in Google Sheets to download the “RAM File” sheet as a CSV (comma separated value) file. Note where the file is located.
This method only requires Java and logisim310.tar
to be
present. It is a little lengthy, but it also requires the least
configuration.
The command is as follows:
java -jar /path/to/logisim310.tar /path/to/processor0004.circ -load /path/to/RAM.csv -tty table > /path/to/trace.tsv
/path/to/logisim310.tar
,
/path/to/processor0004.circ
, /path/to/RAM.csv
and /path/to/trace.tsv
are place holders that should be
replaced by the actual correct path specification to the respective
files. File path specification differs depending on the operating
system. You may need to consult additional tutorials of how to specify
file paths for your specific operating system.
For simplicity (but not organization), placing all the files in the
same folder significantly helps to simplify the command. In the CLI,
change directory (using the command cd
) to where all the
files are saved, then the file paths only need to mention the file name
because all the files are in the working directory.
This step runs the opcode from /path/to/RAM.csv
in
Logisim and generates a trace file /path/to/trace.tsv
.
There is no automatic connection between Logisim and the assembler.
In the assembler, go to the traceRawData
sheet:
File | Import
, then click Upload
./path/to/trace.tsv
.The “analysis” sheet should update after a few moments.
riverSpider
riverSpider
is the name of a package of scripts and
files to automate TTPASM code assembly-load-run-trace-analysis. The
original version was only intended for Linux, but thanks to Omair Qazi,
the tools is also ported to macOS (only differs in instructions) and
Windows (different script files).
For Linux and macOS, you can download riverSpider
as a ZIP file. Then carefully read and follow the
instructions in README.md
.
For Windows, download the same file as for Linux and Mac OS, but follow Omair’s Windows specific instructions.
After riverSpider
is properly installed, a single CLI
command will upload a TTPASM program to the assembler, download the
opcode file, run the opcode in Logisim-TTP, collect the trace data, and
upload the trace data to the assembler. The “analysis” sheet will
automatically update.
The trace, as rendered in the “analysis” sheet, represents what happens during the execution of a program. Note that the current version uses columns F an G to report the line number and actual source code corresponding to the RAM location of the opcode (column A).
In order for a trace to be useful, there are a few suggestions.
This is the bare minimum to make use of the trace. What each instruction does is crucial because otherwise there is no way to interpret the effects of the execution of instructions in the “analysis” sheet.
Copying-and-pasting code from sample programs is okay, but only if the code is well understood.
Understanding means making connections between each instruction does to the related concepts of how the stack is utilized and the C code that is being translated.
Fully understanding the code also means that the developer can predict/anticipate the behavior of a program and compare that with the actual trace.
Even with a complete understanding of the code, a program can still contain faults. That is okay because a trace will help reveal those faults.
Even though the “analysis” sheet shows the line numbers and source code, it is always more helpful to include comments in the code.
Comments should make connections between each instruction and the general context of what the instruction is a part of. This usually means what is on the stack, what C code is being implemented, what is in each involved register, etc.