mirror of
https://github.com/JanNeuendorf/SVC16.git
synced 2025-06-06 19:45:27 +00:00
First work on the assembler tutorial
This commit is contained in:
parent
2bbe0027f2
commit
e4a43777d9
@ -1,8 +1,9 @@
|
|||||||
## The first program
|
## The first program
|
||||||
|
|
||||||
A simple example would be to print all $2^{16}$ possible colors to the screen.
|
A simple example would be to print all $2^{16}$ possible colors to the screen.
|
||||||
We make our lives easier, by mapping each index of the screen-buffer to the color which is encoded with the index.
|
We make our lives easier, by mapping each index of the screen-buffer to the
|
||||||
Here, we use the names of the opcodes instead of their numbers.
|
color which is encoded with the index. Here, we use the names of the opcodes
|
||||||
|
instead of their numbers.
|
||||||
|
|
||||||
```
|
```
|
||||||
Set 501 1 0 // Write the value 1 to address 501
|
Set 501 1 0 // Write the value 1 to address 501
|
||||||
@ -15,7 +16,9 @@ Skip 0 4 503 // Unless we are at the max number, go back 4 instructions
|
|||||||
Sync 0 0 0 // Sync
|
Sync 0 0 0 // Sync
|
||||||
GoTo 0 0 0 // Repeat to keep the window open
|
GoTo 0 0 0 // Repeat to keep the window open
|
||||||
```
|
```
|
||||||
We could rely on the fact that the value at index 500 starts at zero and we did not have to initialize it.
|
|
||||||
|
We could rely on the fact that the value at index 500 starts at zero and we did
|
||||||
|
not have to initialize it.
|
||||||
|
|
||||||
To build a program that we can execute, we could use python:
|
To build a program that we can execute, we could use python:
|
||||||
|
|
||||||
@ -35,6 +38,7 @@ with open("all_colors.svc16", "wb") as f:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Inspecting the file, we should see:
|
Inspecting the file, we should see:
|
||||||
|
|
||||||
```ansi
|
```ansi
|
||||||
➜ hexyl examples/all_colors.svc16 -pv --panels 1
|
➜ hexyl examples/all_colors.svc16 -pv --panels 1
|
||||||
|
|
||||||
@ -53,3 +57,96 @@ When we run this, we get the following output:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Designing a simple assembly language
|
||||||
|
|
||||||
|
If we want to compile the program from the beginning, all we have to do is to
|
||||||
|
replace `Set`, `Add`, `Print` etc. with their corresponding numbers. If we then
|
||||||
|
make our python script into a command line program that reads in this code, does
|
||||||
|
the replacement and produces the binary output, we already have our first
|
||||||
|
assembler.
|
||||||
|
|
||||||
|
### Adding variables
|
||||||
|
|
||||||
|
Not having to remember the opcodes is an improvement, but we still have to
|
||||||
|
manually decide which memory address holds which value. This can be automated
|
||||||
|
relatively easily.
|
||||||
|
|
||||||
|
First, we need to identify variables. This can be easily done with the criterion
|
||||||
|
that they start with a letter and are not an instruction.
|
||||||
|
|
||||||
|
We need to know the first memory address that is not used for instructions.
|
||||||
|
Right now, this is very easily done since every line of our program takes up
|
||||||
|
four values in memory. The first variable name we see gets replaced with the
|
||||||
|
first free address. For all the following ones we check if the variable was
|
||||||
|
assigned before. If it was, we reuse that address, and if not, we reserve a new
|
||||||
|
one.
|
||||||
|
|
||||||
|
Our program can now look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
Set one 1 0
|
||||||
|
Set max_value 65535 0
|
||||||
|
Print color color 0
|
||||||
|
Add color one color
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
This is already much easier to understand.
|
||||||
|
|
||||||
|
### Adding constants
|
||||||
|
|
||||||
|
In the first line of that example we assigned the value 1 to a variable called
|
||||||
|
"one". This is a little catastrophe. In order to get the value 1 into our
|
||||||
|
program, we needed to run an instruction at runtime and take up 5 addresses (4
|
||||||
|
for the instruction, one for the value).
|
||||||
|
|
||||||
|
We want to write the values of constants into our binary directly. The program
|
||||||
|
could look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
Print color color 0
|
||||||
|
Add color "1" color
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The way this is resolved is very similar to the way the variables are assigned.
|
||||||
|
We replace every new constant with the next free address and every reappearing
|
||||||
|
constant with its known address. The only difference is that we have to write
|
||||||
|
the values of the constant to their addresses as well.
|
||||||
|
|
||||||
|
It would be best to change the ordering of variables and constants. The
|
||||||
|
addresses for constants already hold a value when the program starts and the
|
||||||
|
addresses for variables do not. We should put the variables at the end, so the
|
||||||
|
binary file does not contain a bunch of zeros.
|
||||||
|
|
||||||
|
### Simple replacements
|
||||||
|
|
||||||
|
This is a good time to invent some new instructions which are expanded to the
|
||||||
|
known ones. For now, they should have a one to one mapping, meaning that each
|
||||||
|
instruction is replaced by exactly one new one. We can, however, have
|
||||||
|
instructions with fewer arguments. Examples would be:
|
||||||
|
|
||||||
|
```
|
||||||
|
incr variable -> Add variable "1" variable
|
||||||
|
negate variable -> Xor variable "1" variable
|
||||||
|
jump location condition -> GoTo "0" location condition // where location is not a variable
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Labels
|
||||||
|
|
||||||
|
As it stands, we still have to count or remember line numbers for the `Skip` and
|
||||||
|
`GoTo` instructions. One simple Idea would be to allow a label (or multiple) for
|
||||||
|
each line.
|
||||||
|
|
||||||
|
```
|
||||||
|
Print color color 0 <start>
|
||||||
|
Incr color
|
||||||
|
Cmp color "65535" condition
|
||||||
|
negate condition
|
||||||
|
jump @start condition
|
||||||
|
Sync 0 0 0
|
||||||
|
jump @start "0"
|
||||||
|
```
|
||||||
|
Loading…
x
Reference in New Issue
Block a user