Skip to content

Instantly share code, notes, and snippets.

@antimatter15
Created April 17, 2015 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antimatter15/bc568341211710c42cc2 to your computer and use it in GitHub Desktop.
Save antimatter15/bc568341211710c42cc2 to your computer and use it in GitHub Desktop.

Introduction

In this system, we have a single operation— MOV, which moves the contents of one address to another address. These addresses are all absolute and are 16 bits wide, just like their contents.

There is a memory-mapped program counter, which is how control flow is handled.

start:
MOV PC, #start

Here the start: represents a label for that region, and #start represents the address of some spot of memory allocated to hold the constant address represented by start.

This functions as an infinite loop, constantly returning the program counter to the same spot, over and over again.

MOV ret, PC

Here we can take the value of the program counter (which now points to whatever instruction immediately follows) and store it at some address ret.

We can copy the value of some address into some othe rone with

MOV a, b

Numbers

how do i represent numbers?

Numbers are defined by the operations that can be done on them. With a jump table, we can assign different values different properties when operated on. However, we have to eschew the intuitive mapping between their representation and their meaning.

That is, we can considently define arithmetic such that the number 1 is represented as 8200, and 2 as 8204, 3 as 8208 and so forth.

We can implement these numbers as a jump table. Lets say we store some value at a particular address, identified as a. It might be initialized with the value 1, which may be represented as 8200.

how do i recieve data from the outside world?

So it's kind of problematic to have this kind of numerical representation because it's kind of arbitrary and the outside world is much more likely to provide you with ordinary bytes. However, we can (with wires) just wire bits up differently— for instance, one could have an offset so that the low nibble is always zero.

That then gives us enough instructions of leeway to implement some sort of jump table which inlines a finite number of useful instructions.

how do i do arithmetic?

By moving the value of the variable into the program counter, we can essentially jump to that specific address

MOV PC, a

At that address, we might define some set of conditional expressions

.org 8200
mov inc, #2
mov dec, #0
mov PC, #ret0

Essentially, what we do is we store some pointer at some address which represents a number. We jump to the address at that pointer, which sets some other regions of memory with the appropriate values. We return execution to some ret pointer which is set shortly before calling the number.

In pseudocode, the process of incrementing a value stored at a

mov ret, #next
mov pc, a
next:
mov a, inc

how do i do control flow?

Rather than a single ret register, we can have several registers depending on the contents of a particular value. For instance, if a number is zero, we can jump to the address stored in ret0. This changes the code for incrementing values slightly

mov ret, #next
mov ret0, #next
mov pc, a
next:
mov a, inc

But this enables neat control flow abilities

mov ret, #nonzero
mov ret0, #zero
mov pc, a
zero:
; instructions to do if it's zero
nonzero:
; instructions to do if it's nonzero

Addition

42 + 19

pseudocode:

while b > 0
    inc a
    dec b

pseudomovasm

.org a, #42
.org b, #19

mov a, #42
mov b, #19

loop:
mov ret, #next1
mov ret0, #finish
mov pc, b
next1:
    mov ret, #next2
    mov ret0, #next2
    mov pc, a
    next2:
    mov a, inc
    
    mov ret, #next3
    mov ret0, #next3
    mov pc, b
    next3:
    mov b, dec
finish:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment