mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-19 10:36:43 +00:00
Added ToC + labels + dw, expanded on equ
parent
f707426b23
commit
e05b3d0082
@ -1,7 +1,33 @@
|
|||||||
# equ
|
## 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 `equ` directive allows you to give a name to certain special values. This code:
|
The following directives are explained:
|
||||||
|
- [EQU](#equ)
|
||||||
|
- [Labels](#labels)
|
||||||
|
- [DW](#dw)
|
||||||
|
- [DUP](#dup)
|
||||||
|
- [Sections](#sections)
|
||||||
|
- [Strings](#strings)
|
||||||
|
- [Characters](#characters)
|
||||||
|
- [ORG](#org)
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
```c
|
||||||
|
#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:
|
||||||
|
```s
|
||||||
|
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 `EQU` directive is (as all instructions are) case insensitive. So `equ`, `eQu` and `EqU` make no difference
|
||||||
|
***
|
||||||
|
|
||||||
|
So this code:
|
||||||
|
```s
|
||||||
INT_LEGS equ 0x0001
|
INT_LEGS equ 0x0001
|
||||||
LEGS_SET_DIRECTION equ 0x0001
|
LEGS_SET_DIRECTION equ 0x0001
|
||||||
NORTH equ 0x0000
|
NORTH equ 0x0000
|
||||||
@ -9,20 +35,80 @@ The `equ` directive allows you to give a name to certain special values. This co
|
|||||||
MOV A, LEGS_SET_DIRECTION
|
MOV A, LEGS_SET_DIRECTION
|
||||||
MOV B, NORTH
|
MOV B, NORTH
|
||||||
HWI INT_LEGS
|
HWI INT_LEGS
|
||||||
|
```
|
||||||
translates to:
|
produces the same machine code as:
|
||||||
|
```s
|
||||||
MOV A, 0x0001
|
MOV A, 0x0001
|
||||||
MOV B, 0x0000
|
MOV B, 0x0000
|
||||||
HWI 0x0001
|
HWI 0x0001
|
||||||
|
```
|
||||||
|
but to make code more readable and easier to reason about it is encouraged to use constants. Check this [snippet](https://github.com/simon987/Much-Assembly-Required/wiki/Snippet:-Constants) of al sort's of useful constants.
|
||||||
|
|
||||||
but is much easier to understand.
|
## 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:
|
||||||
|
```s
|
||||||
|
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:
|
||||||
|
```s
|
||||||
|
MOV A, 0xDeaD ;; move 0xDead (valid hex number) into register A
|
||||||
|
call someFunc ;; call 'someFunc'
|
||||||
|
|
||||||
# TODO:
|
someFunc: ;; label 'someFunc'
|
||||||
labels
|
MOV A, 0xBeeF ;; move 0xBeeF (also valid hex number) into register A
|
||||||
equ
|
ret ;; return from function call
|
||||||
dup
|
```
|
||||||
ORG
|
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:
|
||||||
dw
|
```s
|
||||||
strings
|
MOV A, 0xDeaD ;; 0x0000 - instruction memory address
|
||||||
sections
|
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:
|
||||||
|
```s
|
||||||
|
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:
|
||||||
|
1. You want to pad out certain area's in your program/memory.
|
||||||
|
2. You want to put a `global` and/or `static` variable in your code.
|
||||||
|
3. 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:
|
||||||
|
```s
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## DUP
|
||||||
|
The `DUP` directive (Duplicate) is used as operand for the `DW` directive. The syntax:
|
||||||
|
```s
|
||||||
|
;; [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
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
## Strings
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
## Characters
|
||||||
|
// NOT IMPLEMENTED
|
||||||
|
|
||||||
|
## ORG
|
||||||
|
// TODO
|
||||||
|
Loading…
x
Reference in New Issue
Block a user