1
0
notes/website/2018-02-06-infernal-interpreter.md

106 lines
4.7 KiB
Markdown
Raw Normal View History

2024-03-10 13:53:47 +00:00
# Infernal Interpreter
## The dComArk Course ##
My first semester of University (summer 2015) I had a course named
**Computer Architecture** commonly shorted to **dComArk**. It was a
standard course about the low level construction of modern computers.
It followed [Tanenbaum](http://www.cs.vu.nl/~ast/)'s classic
[Structured Computer
Organization](http://www.mypearsonstore.com/bookstore/structured-computer-organization-9780132916523).
The course itself was known for its [idiosyncratic
lecturer](https://twitter.com/nielsolofbouvin), and for being hard as
hell. Topics included registers, the stack, assembly code,
micro-code, and the architecture of processors in general.
Jumping directly from just having learnt Java, as a first programming
language, to suddenly having to understand and write low-level
programming languages such as
[IJVM](https://en.wikipedia.org/wiki/IJVM) and [X86-64
assembly](https://en.wikipedia.org/wiki/X86-64), was tough, and many
of my fellow students dropped out because of it.
My favorite assignment was the one where we extended IJVM
with a new op-code. You see, some processors are programmable, in
their own [highly restricted programming
language](https://en.wikipedia.org/wiki/MIC-1). Changing something you
think is set in stone - like the set of op-codes a processor has -
changes the way you see the world.
But this article is neither about IJVM, nor about micro-code. It's
about the course's fifth and final assignment. For this assignment we
were to write a recursive [fibonnaci
function](https://rosettacode.org/wiki/Fibonacci_sequence) in x86-64,
and then describe how it worked, with visualizations of the registers
and stack at every instruction.
![Example of the recursive Fibonacci function in x86, with
2024-03-10 14:19:08 +00:00
comments.](images/infernal-interpreter-example.png)
2024-03-10 13:53:47 +00:00
[A friend of mine](https://christoffer.space/) spent an entire evening
on this assignment carefully drawing the [registers and stack into
2024-03-10 14:19:08 +00:00
Excel](images/infernal-interpreter_christoffer-stack.pdf).
2024-03-10 13:53:47 +00:00
I decided I'd rather spend an evening programming, than messing about
with Excel, so I began writing a program that could generate code for
embedding into LaTeX. The program needed to emulate just enough
X86-64 to run the function, and no more.
## The Infernal Interpreter ##
<!--start-->
![Example of Infernal Interpreter output. Columns describe the
movement of data when executing x86
2024-03-10 14:19:08 +00:00
op-codes.](images/infernal-interpreter-output-ascii.png)
2024-03-10 13:53:47 +00:00
**Infernal Interpreter** is an emulator and visualizer of a subset of
the AMD x86-64 ABI, using the GAS syntax. You give it a bunch of
symbolic machine code, after which it produces a visualization of the
running code, either to the terminal, or as a LaTeX file with Tikz.
It's old, written in Python 2, and for an incredibly specific purpose,
but I enjoy going back and looking at the output.
<!--end-->
There is something at once uncomfortable and fascinating about looking
at old code. Thoughts of "How could I ever write code this bad?" and
"Damned, I've gotten a lot better since then". While writing this
article I wanted some images that fits the style of my website, so I
added a `ascii` painting mode, that shows the trace in the terminal.
This was non-trivial, given the existing structures, which were
clearly designed to be as obscure as possible. Along the way the
frontend was updated to be more UNIX-like. The backend is a nightmare,
and has been kept without major changes.
If you'd like to take at look at it as well, you can find an [an
example of the tikz output
2024-03-10 14:19:08 +00:00
here](images/infernal-interpreter_tikz-example.pdf).
2024-03-10 13:53:47 +00:00
Alternatively you can [download the program
2024-03-10 14:19:08 +00:00
itself](images/infernal-interpreter_source-1.0.0.zip), or
2024-03-10 13:53:47 +00:00
[view the official Git
repository](https://gitfub.space/Jmaa/infernal-interpreter).
**Infernal Interpreter** requires **Python 2**, and will crash on
anything remotely complicated. Notably: it does not model the heap.
The source-code is available under the BEERWARE license, so you are
free to modify it as you like.
![Example of Infernal Interpreter output, with the Tikz painter.
Columns describe the movement of data when executing x86
2024-03-10 14:19:08 +00:00
op-codes.](images/infernal-interpreter-output-tikz.png)
2024-03-10 13:53:47 +00:00
The program includes two example files in the `examples` folder, both
of which were part of my assignment, and has been included unaltered.
You can run them with a command like this:
./infernal
-i=examples/fibonnaci_recursive.S
--rdi=3
The `--rdi=3` argument is important, because it sets the `%rdi`
register to `3`, and thus tells the program to compute the 3rd
Fibonacci number. This writes ascii directly to the terminal. To
produce Tikz, simply change the painter: `--painter tikz`. The full
options can be found by running `./infernal --help`