Table of Contents
Directives
Directives is the name for the group of terms/strings that have special meaning in a MAR program (or any compiled program). These directives are special instruction for the compiler (in assembly we call them an assembler). Directives state certain things about the code that make the compiler generate the machine code in the way the programmer want's to.
The following directives are explained:
EQU
The EQU directive allows you to define compile time constants. If you are familiar with the C pre processor think of it as the #define directive:
#define name 1 // for the rest of the program any instance of 'name' will be replaced with '1'
The syntax for the EQU directive is as followed:
name EQU 0x01 ;; for the rest of the program any instance of 'name' will be replaced with '0x01'
These directives can be used to give a name to a constant value (it never changes). When assembling the compiler will swap all the found instances of this name with the value specified to it. Remember that the name is only known at compile time, after compilation there is no concept of the name you gave to the constant.
NOTE: the
EQUdirective is (as all instructions are) case insensitive. Soequ,eQuandEqUmake no difference
So this code:
    INT_LEGS           equ 0x0001
    LEGS_SET_DIRECTION equ 0x0001
    NORTH              equ 0x0000
    MOV A, LEGS_SET_DIRECTION
    MOV B, NORTH
    HWI INT_LEGS
produces the same machine code as:
    MOV A, 0x0001
    MOV B, 0x0000
    HWI 0x0001
but to make code more readable and easier to reason about it is encouraged to use constants. Check this snippet of al sort's of useful constants.
Labels
The label directive associates a label with the memory address of the instruction/directive that follows it. The syntax to use a label is this: name_of_label: <instruction>. Labels behave a bit like the EQU directive. They refer to a certain value. Only this time it is not a constant value but a memory address. This is useful for the JMP family instructions and the DW directive. See the following example:
    MOV A, 0         ;; set register A to the value of 0
infinite_loop:       ;; create a label called 'infinite_loop'
    CMP A, 0         ;; check if register A has the value of 0
    JZ infinite_loop ;; if A has the value of 0 we jump back to the label infinite loop
    ;; the label prefixes the 'CMP A, 0' instruction so the jump goes to that instruction
    ;; because the value in A never changes we are stuck in an infinite loop
So it might look like the JZ is jumping to the infinite_loop label but actually it is jumping to the CMP A, 0 instruction behind it. The labels leave no footprint in the compiled machine code and are replaced by the memory addresses they refer to. Another example of a label used with a function/routine call:
    MOV A, 0xDeaD ;; move 0xDead (valid hex number) into register A
    call someFunc ;; call 'someFunc'
someFunc:         ;; label 'someFunc'
    MOV A, 0xBeeF ;; move 0xBeeF (also valid hex number) into register A
    ret           ;; return from function call
So for the programmer it is quite readable what happens here but on compilation the labels are removed and replaced with the memory addresses so it looks more like this:
    MOV A, 0xDeaD  ;; 0x0000 - instruction memory address
    call   0x0002  ;; 0x0001
    MOV A, 0xBeeF  ;; 0x0002
    ret            ;; 0x0003
NOTE: Instructions are actually 1-3 words (2-6 bytes) of size, but simplified for the above example.
DW
The DW word directive (Define Word) allows the programmer to put a value in memory. The syntax for DW is:
    DW 0x000
    DW 0x000, 0x0001, 0x0002, 0x0003 ;; .... and go on for how long you want
As you can see we can just dump values right at that memory spot. This can be useful for multiple reasons:
- You want to pad out certain area's in your program/memory.
 - You want to put a 
globaland/orstaticvariable in your code. - You want to define constant strings. (Yeah the most useful one) To prevent headaches of finding out where you put the literal in memory you can use labels:
 
mynumber: DW 0x0000
    MOV A, [mynumber] ;; NOTE: mynumber points to the memory location not the actual value.
                      ;;       use [] to reference the contents of the memory
String literals
You can use the DW to store strings, for example:
my_str: DW "Hello"
; This is assembled to:
;  00 48 00 65 00 6C 00 6C 00 6F 
.text
MOV A, [my_str] ; Value of A is now 'H'
Java escape sequences are handled (\u0000, \". \0 \t etc) and strings are encoded to 16-bit big endian.
You can combine any type of literal values in a single line, for example:
DW "some string", 123, "another string", 0
DUP
The DUP directive (Duplicate) is used as operand for the DW directive. The syntax:
;; [label:] DW amount DUP(value)
someBigStaticMemoryBlock: DW 100 DUP(0x20), 0
;; this create 100 times a 0x20 (the space character) followed by a 0 (null terminator)
It can only be used in combination with the DW directive
Sections
Sections are useful to organize your code.
There is currently two section, .text and .data. By default, the .data section implicitly starts at the beginning of your code and ends where the .text section starts, but you are allowed to reorder them as you wish. You must explicitly specify where the .text section starts.
At the beginning of each tick, your code is executed starting at the first instruction after the .text directive until it reaches the BRK instruction (See Execution cycle).
Notes:
- There is nothing stopping you from executing code in the 
.datasection (or to store variables in the.textsection) - There is no padding in between sections
 
ORG
The ORG directive lets you change where your code is copied during assembly. By default, assembled code is copied at 0x200
Example:
ORG 0x8000
my_var: DW 0x1234
.text
MOV A, my_var ; Value of A is now 0x8000
brk