# Eremius
![eremiusheader](https://github.com/tom-hewitt/eremius/assets/47860067/ea62bfe9-3d24-4453-b88d-b0e5ee83cc4d)
an assembler, emulator, and debugger for a subset of the ARM assembly language
### This project is a work in progress
- The assembler is (mostly!) complete for the chosen subset of the specification.
- The emulator is in the middle of a rewrite to align its functionality with the exact behaviour specified in the ARM manual, so isn't currently fully functional.
- There is an accompanying browser-based debugger that is currently in a different repository - I'm working on polishing it up and then I'm planning to integrate the entire project into a single monorepo.
Feel free to get in touch or raise a github issue, and check back soon for updates!
## What's in a name?
eremius' predecessors _Komodo_, _Perentie_, and _Bennett_, developed at the University of Manchester, are all named after monitor lizards. _Varanus Eremius_ is the latin name for the Rusty Desert Monitor Lizard - a nod to the project's predecessors and it's implementation language.
## Contents
1. [Supported Mnemonics](#supported-mnemonics)
2. [Condition Flags](#condition-flags)
3. [Operands](#operands)
4. [Labels](#labels)
5. [Instructions](#instructions)
6. [Assembler Overview](#assembler-overview)
7. [Testing](#testing)
## Supported Mnemonics
| Category | Mnemonic | Status |
| ------------------- | -------------------------------------- | ------ |
| Branch | [B](#b---branch) | |
| Data Processing | [ADD](#add---add) | |
| | [SUB](#sub---subtract) | |
| | [CMP](#cmp---compare) | |
| | [MOV](#mov---move) | |
| Data Transfer | [LDR](#ldr---load-register) | |
| | [STR](#str---store-register) | |
| | [LDRB](#ldrb---load-register-byte) | |
| | [STRB](#strb---store-register-byte) | |
| | [LDM](#ldm---load-multiple) | |
| | [STM](#stm---store-multiple) | |
| System Call | [SVC](#svc---supervisor-call) | |
| Pseudo-Instruction | [ADR](#adr---address-register) | |
| Assembler Directive | [DEFW](#defw---define-words) | |
| | [DEFB](#defb---define-byte) | |
| | [DEFS](#defs---define-space) | |
| | [ORIGIN](#origin---set-origin-address) | |
| | [ALIGN](#align---align-address) | |
| | [ENTRY](#entry---set-entry-point) | |
| | [EQU](#equ---equals) | |
## Condition Flags
| Mnemonic Extension | Meaning |
| ------------------ | --------- |
| `EQ` | Equal |
| `NE` | Not Equal |
| `CS`/`HS` | Carry Set/Unsigned Higher or Same |
| `CC`/`LO` | Carry Clear/Unsigned Lower |
| `MI` | Minus (Negative) |
| `PL` | Plus (Positive or Zero) |
| `VS` | Overflow |
| `VC` | No Overflow |
| `HI` | Unsigned Higher |
| `LS` | Unsigned Lower or Same |
| `GE` | Signed Greater Than or Equal |
| `LT` | Signed Less Than |
| `GT` | Signed Greater Than |
| `LE` | Signed Less Than or Equal |
| `AL` | Always (Unconditional) |
## Operands
### Shifter Operands
There are 4 types of shifter operands:
| Format | Name |
| ----------------------------- | ----------------------------- |
| `#` | Immediate |
| `` | Register |
| `, #` | Register Shift By Immediate |
| `, ` | Register Shift By Register |
### Load/Store Address Operands
All addressing modes involve a base register and an offset.
There are 3 types of offset value:
| Format | Name |
| ------------------ | --------- |
| `#+/-` | Immediate |
| `+/-` | Register |
| `+/-, #` | Scaled Register |
There are also 3 types of offset:
| Format | Name |
| -------------------- | ------------ |
| `[, #]` | Offset |
| `[, #]!` | Pre-Indexed |
| `[], #` | Post-Indexed |
The 9 combinations of these formats form the 9 possible addressing modes.
## Labels
A Label is a program-relative address that can be assigned to any line in the program.
## Instructions
### B - Branch
Causes a branch to a target address.
#### Syntax
```
B{L}{}
```
#### Flags
| | Behaviour |
| ------ | --------- |
|`L` | Specifies that the instruction should store a return address in the link register (R14) |
|``| Specifies under what circumstances the instruction should be executed (see [Condition Flags](#condition-flags))|
#### Operands
| | Behaviour |
| ----------------- |-----------|
|`` | Specifies the address to branch to |
### ADD - Add
Adds two values. Can optionally update the condition flags based on the result.
#### Syntax
```
ADD{}{S} , ,
```
#### Flags
| | Behaviour |
|--------|-----------|
|``| Specifies under what circumstances the instruction should be executed (see [Condition Flags](#condition-flags))|
|`S` | Specifies that the instruction should update the Current Program Status Register (CPSR) Flags |
#### Operands
| | Behaviour |
| ------------------- | --------- |
|`` | Specifies the destination register |
|`` | Specifies the register that contains the first operand |
|`` | Specifies the second operand (see [Shifter Operands](#shifter-operands))
### SUB - Subtract
Subtracts one value from another. Can optionally update the condition flags based on the result.
#### Syntax
```
ADD{}{S} , ,
```
#### Flags
| | Behaviour |
|--------|-----------|
|``| Specifies under what circumstances the instruction should be executed (see [Condition Flags](#condition-flags))|
|`S` | Specifies that the instruction should update the Current Program Status Register (CPSR) Flags |
#### Operands
| | Behaviour |
| ------------------- | --------- |
|`` | Specifies the destination register |
|`` | Specifies the register that contains the first operand |
|`` | Specifies the second operand (see [Shifter Operands](#shifter-operands))
### CMP - Compare
Compares two values, always updating the condition flags.
#### Syntax
```
CMP{} ,
```
#### Flags
| | Behaviour |
|--------|-----------|
|``| Specifies under what circumstances the instruction should be executed (see [Condition Flags](#condition-flags))|
#### Operands
| | Behaviour |
| ------------------- | --------- |
|`` | Specifies the register that contains the first operand |
|`` | Specifies the second operand (see [Shifter Operands](#shifter-operands))
### MOV - Move
Writes a value to a register.
#### Syntax
```
MOV{}{S} ,
```
#### Flags
| | Behaviour |
|--------|-----------|
|``| Specifies under what circumstances the instruction should be executed (see [Condition Flags](#condition-flags))|
|`S` | Specifies that the instruction should update the Current Program Status Register (CPSR) Flags |
#### Operands
| | Behaviour |
| ------------------- | --------- |
|`` | Specifies the destination register |
|`` | Specifies the operand (see [Shifter Operands](#shifter-operands))
#### Flags
| | Behaviour |
|--------|-----------|
|``| Specifies under what circumstances the instruction should be executed (see [Condition Flags](#condition-flags))|
|`S` | Specifies that the instruction should update the Current Program Status Register (CPSR) Flags |
#### Operands
| | Behaviour |
| ------------------- | --------- |
|`` | Specifies the destination register |
|`` | Specifies the operand (see [Shifter Operands](#shifter-operands))
### LDR - Load Register
Loads a word into a register.
When used with a constant, this is a psuedo-instruction that the assembler will replace with either a data processing isntruction or an `LDR` instruction pointing to a literal in memory.
#### Syntax
```
LDR{} ,