diff --git a/assembler%2Fusage.md b/assembler%2Fusage.md index 174c593..61a6cac 100644 --- a/assembler%2Fusage.md +++ b/assembler%2Fusage.md @@ -4,892 +4,424 @@ This document provides a comprehensive reference for the DSA (Damn Simple Architecture) assembly language, including all hardware instructions and pseudo-instructions with their syntax variations and usage examples. -**Contents** -- [Registers](https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture/wiki/assembler%2Fusage#registers) -- [Hardware Instructions](https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture/wiki/assembler%2Fusage#hardware-instructions) -- [Pseudo Instructions](https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture/wiki/assembler%2Fusage#pseudo-instructions) -- [Code Examples](https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture/wiki/assembler%2Fusage#example-programs-and-libraries) +## Calling Convention +| Step | Responsibility | Action | Description | +|------|----------------|--------|-------------| +| 1 | **Caller** | Push arguments | Push exactly n arguments to the stack (in order, last argument pushed first) | +| 2 | **Caller** | Call function | Execute `call namespace::function` - this automatically pushes the return address (pcx) and jumps to the function | +| 3 | **Function** | Set up stack frame | Execute `push bpr; mov spr, bpr` to establish new stack frame | +| 4 | **Function** | Access arguments | Read arguments starting at `spr+8` (first 3 args at offsets 8, 12, 16) | +| 5 | **Function** | Execute function | Perform the function's operations using the arguments | +| 6 | **Function** | Store return value | Write return value (if any) to `spr+8` | +| 7 | **Function** | Restore stack frame | Execute `mov bpr, spr; pop bpr` to restore previous stack frame | +| 8 | **Function** | Return | Execute `return` pseudo-instruction to return to caller | +| 9 | **Caller** | Clean up stack | Pop exactly n arguments from the stack to clean up | +| 10 | **Caller** | Handle unused values | Use `pop zero` to discard any unused stack values if needed | -## Syntax Conventions - -- `reg` - Register operand -- `imm` - Immediate value (16-bit for I-type instructions) -- `addr` - Memory address or label -- `offset` - Memory offset (optional, defaults to 0) -- `[]` - Optional parameters -- `|` - Alternative syntax options +**Notes:** +- The namespace in step 2 is the name assigned in the `include` statement +- The `call` pseudo-instruction automatically handles return address management so long as the callee does not mess with the stack +- Arguments are accessed by the callee using offsets from the base pointer (bpr) ## Registers -- general purpose: `rg0-rgf` - - be careful when using `rgf` for storing data as some pseduo-instructions may implicitly overwrite this register. -- special registers: - - `acc` - the accumulator. useful for storing the results of calculations, especially in iterators where a temporary register may be needed. - - `spr` - stack pointer. once you've written the stack location to this, you likely won't need to worry about it, as push/pop pseduo-instructions abstract over this. - - `bpr` - base pointer for the stack. - - `ret` - return address register. if you're writing a function, it is good practice to store return addresses here. - start functions with `pop ret` and end them with `jmp 4, ret` for a seamless call/return flow, assuming the function was called like `push pcx; jmp function` - - `idr` - **(privilleged)** holds the address of interrupt descriptor table - - `mmr` - **(privilleged)** holds the address of hardware memory map table - - `zero` - **(read only)** literally just zero. - - `pcx` - **(read only)** program counter, useful for function return addresses. - - `noreg` **(placeholder)** this indicates the absence of a register argument. has the same effect as leaving an operand blank. +| Register | Type | Description | +|----------|------|---------------------------------------------------------------------------------------------------| +| `rg0-rgf` | General Purpose | General-purpose registers. Use `rgf` carefully as pseudo-instructions may overwrite it | +| `acc` | Special | Accumulator for calculations and temporary storage | +| `spr` | Special | Stack pointer | +| `bpr` | Special | Base pointer for stack frames | +| `ret` | Special | Return address register | +| `idr` | Privileged | Interrupt descriptor table address
**on-read/write: protection fault (unless in kernel mode)** | +| `mmr` | Privileged | Hardware memory map table address
**on-read/write: protection fault (unless in kernel mode)** | +| `zero` | Read-only | Always contains zero
**on-read: always returns zero**
**on-write: value is voided** | +| `pcx` | Read-only | Program counter
**on-write: protection fault** | +| `noreg` | Placeholder | Indicates absence of register argument
**on-read/write: illegal instruction fault** | ## Hardware Instructions ### Data Movement Instructions -#### MOV - Move Register to Register +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **MOV** | `src_reg, dest_reg` | Copy value from source to destination register | +| **MOVS** | `src_reg, dest_reg` | Copy with sign extension | -```assembly -mov src_reg, dest_reg -``` - -**Example:** - -```assembly -mov rg0, rg1 ; Copy value from rg0 to rg1 -mov acc, rg2 ; Copy accumulator to rg2 -``` - -#### MOVS - Move with Sign Extension - -```assembly -movs src_reg, dest_reg -``` - -**Example:** - -```assembly +**Examples:** +```dsa +mov rg0, rg1 ; Copy rg0 to rg1 movs rg0, rg1 ; Copy rg0 to rg1 with sign extension ``` - ### Memory Access Instructions #### Load Instructions -##### LDB - Load Byte - -```assembly -ldb base_reg, dest_reg [, offset] -ldb label, dest_reg [, offset] -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **LDB** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte from memory | +| **LDBS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte with sign extension | +| **LDH** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word (16-bit) | +| **LDHS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word with sign extension | +| **LDW** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load word (32-bit) | **Examples:** - -```assembly +```dsa ; Direct register addressing -ldb rg0, rg1 ; Load byte from address in rg0 to rg1 -ldb rg0, rg1, 5 ; Load byte from (rg0 + 5) to rg1 - -; Label addressing - expands to multiple instructions -ldb buffer, rg2 ; Load byte from label 'buffer' to rg2 -``` - -**Label expansion:** When using a label, `ldb buffer, rg2` expands to: - -```assembly -lli buffer, rg2 ; Load lower 16 bits of buffer address -lui buffer, rg2 ; Load upper 16 bits of buffer address -ldb rg2, rg2 ; Load byte from address in rg2 to rg2 -``` - -**With offset:** `ldb buffer, rg2, 10` expands to: - -```assembly -lli buffer, rg2 ; Load lower 16 bits of buffer address -lui buffer, rg2 ; Load upper 16 bits of buffer address -ldb rg2, rg2, 10 ; Load byte from (rg2 + 10) to rg2 -``` - -##### LDBS - Load Byte (Sign Extended) - -```assembly -ldbs base_reg, dest_reg [, offset] -ldbs label, dest_reg [, offset] -``` - -**Examples:** - -```assembly -; Direct register addressing -ldbs rg0, rg1 ; Load sign-extended byte from rg0 to rg1 -ldbs rg0, rg1, 10 ; Load sign-extended byte from (rg0 + 10) - -; Label addressing -ldbs data_array, rg3 ; Load sign-extended byte from 'data_array' -``` - -**Label expansion:** `ldbs data_array, rg3` expands to: - -```assembly -lli data_array, rg3 ; Load lower 16 bits of data_array address -lui data_array, rg3 ; Load upper 16 bits of data_array address -ldbs rg3, rg3 ; Load sign-extended byte from rg3 to rg3 -``` - -##### LDH - Load Half-word - -```assembly -ldh base_reg, dest_reg [, offset] -ldh label, dest_reg [, offset] -``` - -**Examples:** - -```assembly -; Direct register addressing -ldh rg0, rg1 ; Load 16-bit value from rg0 to rg1 -ldh rg0, rg1, 2 ; Load 16-bit value from (rg0 + 2) - -; Label addressing -ldh config_table, rg4 ; Load half-word from 'config_table' -``` - -**Label expansion:** `ldh config_table, rg4, 6` expands to: - -```assembly -lli config_table, rg4 ; Load lower 16 bits of config_table address -lui config_table, rg4 ; Load upper 16 bits of config_table address -ldh rg4, rg4, 6 ; Load half-word from (rg4 + 6) to rg4 -``` - -##### LDHS - Load Half-word (Sign Extended) - -```assembly -ldhs base_reg, dest_reg [, offset] -ldhs label, dest_reg [, offset] -``` - -**Examples:** - -```assembly -; Direct register addressing -ldhs rg0, rg1 ; Load sign-extended 16-bit value -ldhs rg0, rg1, 4 ; Load from (rg0 + 4) with sign extension - -; Label addressing -ldhs signed_values, rg5 ; Load sign-extended half-word from label -``` - -**Label expansion:** `ldhs signed_values, rg5` expands to: - -```assembly -lli signed_values, rg5 ; Load lower 16 bits of signed_values address -lui signed_values, rg5 ; Load upper 16 bits of signed_values address -ldhs rg5, rg5 ; Load sign-extended half-word from rg5 to rg5 -``` - -##### LDW - Load Word - -```assembly -ldw base_reg, dest_reg [, offset] -ldw label, dest_reg [, offset] -``` - -**Examples:** - -```assembly -; Direct register addressing -ldw rg0, rg1 ; Load 32-bit word from rg0 to rg1 +ldb rg0, rg1 ; Load byte from address in rg0 ldw rg0, rg1, 8 ; Load word from (rg0 + 8) ; Label addressing +ldb buffer, rg2 ; Load byte from label 'buffer' ldw stack, bpr ; Load stack address into base pointer -ldw current, rg1 ; Load word from 'current' variable ``` +**Label Expansions:** +```dsa +; ldb buffer, rg2 expands to: +lli buffer, rg2 ; Load lower 16 bits of buffer address +lui buffer, rg2 ; Load upper 16 bits of buffer address +ldb rg2, rg2 ; Load byte from address in rg2 -**Label expansion:** `ldw stack, bpr` expands to: - -```assembly +; ldw stack, bpr expands to: lli stack, bpr ; Load lower 16 bits of stack address lui stack, bpr ; Load upper 16 bits of stack address -ldw bpr, bpr ; Load word from address in bpr to bpr +ldw bpr, bpr ; Load word from address in bpr ``` - #### Store Instructions -##### STB - Store Byte - -```assembly -stb src_reg, base_reg [, offset] -stb src_reg, label [, offset] -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **STB** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store byte to memory | +| **STH** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store half-word to memory | +| **STW** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store word to memory | **Examples:** - -```assembly +```dsa ; Direct register addressing stb rg0, rg1 ; Store byte from rg0 to address in rg1 -stb rg0, rg1, 3 ; Store byte to (rg1 + 3) +stw rg0, rg1, 12 ; Store word to (rg1 + 12) ; Label addressing stb acc, buffer ; Store byte from accumulator to 'buffer' -stb rg2, output, 5 ; Store byte to (output + 5) -``` - -**Label expansion:** When using a label, `stb acc, buffer` expands to: - -```assembly -lli buffer, rgf ; Load lower 16 bits of buffer address to temp register -lui buffer, rgf ; Load upper 16 bits of buffer address to temp register -stb acc, rgf ; Store byte from acc to address in rgf -``` - -**With offset:** `stb rg2, output, 5` expands to: - -```assembly -lli output, rgf ; Load lower 16 bits of output address -lui output, rgf ; Load upper 16 bits of output address -stb rg2, rgf, 5 ; Store byte to (rgf + 5) -``` - -##### STH - Store Half-word - -```assembly -sth src_reg, base_reg [, offset] -sth src_reg, label [, offset] -``` - -**Examples:** - -```assembly -; Direct register addressing -sth rg0, rg1 ; Store 16-bit value from rg0 -sth rg0, rg1, 6 ; Store to (rg1 + 6) - -; Label addressing -sth rg3, config_word ; Store half-word to 'config_word' -sth acc, data_table, 12 ; Store to (data_table + 12) -``` - -**Label expansion:** `sth rg3, config_word` expands to: - -```assembly -lli config_word, rgf ; Load lower 16 bits of config_word address -lui config_word, rgf ; Load upper 16 bits of config_word address -sth rg3, rgf ; Store half-word from rg3 to address in rgf -``` - -##### STW - Store Word - -```assembly -stw src_reg, base_reg [, offset] -stw src_reg, label [, offset] -``` - -**Examples:** - -```assembly -; Direct register addressing -stw rg0, rg1 ; Store 32-bit word from rg0 -stw rg0, rg1, 12 ; Store to (rg1 + 12) - -; Label addressing stw rg1, current ; Store word to 'current' variable -stw acc, result_buffer, 8 ; Store accumulator to (result_buffer + 8) ``` +**Label Expansions:** +```dsa +; stb acc, buffer expands to: +lli buffer, rgf ; Load lower 16 bits of buffer address +lui buffer, rgf ; Load upper 16 bits of buffer address +stb acc, rgf ; Store byte from acc to address in rgf -**Label expansion:** `stw rg1, current` expands to: - -```assembly +; stw rg1, current expands to: lli current, rgf ; Load lower 16 bits of current address lui current, rgf ; Load upper 16 bits of current address stw rg1, rgf ; Store word from rg1 to address in rgf ``` - -**Complex example with label and offset:** `stw acc, array_base, 16` expands to: - -```assembly -lli array_base, rgf ; Load lower 16 bits of array_base address -lui array_base, rgf ; Load upper 16 bits of array_base address -stw acc, rgf, 16 ; Store accumulator to (rgf + 16) -``` - ### Immediate Load Instructions -#### LLI - Load Lower Immediate +| Mnemonic | Operands | Description | +|----------|----------|------------------------------------------------------------------------| +| **LLI** | `imm, dest_reg` | Load 16-bit immediate into lower 16 bits
**Clears upper 16 bits!** | +| **LUI** | `imm, dest_reg` | Load 16-bit immediate into upper 16 bits | -```assembly -lli imm, dest_reg -``` +**Usage** + +ensure that you always run **Lli** before **Lui** as **Lli** clears the upper 16 bits. **Examples:** - -```assembly +```dsa lli 0x1234, rg0 ; Load 0x1234 into lower 16 bits of rg0 -lli 100, acc ; Load 100 into lower 16 bits of accumulator -``` - -#### LUI - Load Upper Immediate - -```assembly -lui imm, dest_reg -``` - -**Examples:** - -```assembly lui 0xABCD, rg0 ; Load 0xABCD into upper 16 bits of rg0 -lui 200, acc ; Load 200 into upper 16 bits of accumulator ``` - ### Jump Instructions -#### JMP - Unconditional Jump - -```assembly -jmp addr [, offset_reg] -jmp imm, offset_reg -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **JMP** | `addr [, offset_reg]`
`imm, offset_reg` | Unconditional jump | +| **JEQ** | `addr [, offset_reg]` | Jump if equal flag set | +| **JNE** | `addr [, offset_reg]` | Jump if not equal flag set | +| **JGT** | `addr [, offset_reg]` | Jump if greater than flag set | +| **JGE** | `addr [, offset_reg]` | Jump if greater or equal flags set | +| **JLT** | `addr [, offset_reg]` | Jump if less than flag set | +| **JLE** | `addr [, offset_reg]` | Jump if less or equal flags set | **Examples:** - -```assembly +```dsa jmp start ; Jump to label 'start' jmp 4, ret ; Jump to address (4 + ret register) -jmp loop ; Jump to label 'loop' -``` - -#### Conditional Jumps - -##### JEQ - Jump if Equal - -```assembly -jeq addr [, offset_reg] -``` - -**Examples:** - -```assembly jeq end ; Jump to 'end' if equal flag set -jeq 8, ret ; Jump to (8 + ret) if equal +jgt loop ; Jump to 'loop' if greater than flag set ``` - -##### JNE - Jump if Not Equal - -```assembly -jne addr [, offset_reg] -``` - -**Examples:** - -```assembly -jne loop ; Jump to 'loop' if not equal -jne continue ; Jump to 'continue' if not equal -``` - -##### JGT - Jump if Greater Than - -```assembly -jgt addr [, offset_reg] -``` - -**Examples:** - -```assembly -jgt start ; Jump to 'start' if greater than flag set -jgt positive ; Jump to 'positive' if greater -``` - -##### JGE - Jump if Greater or Equal - -```assembly -jge addr [, offset_reg] -``` - -##### JLT - Jump if Less Than - -```assembly -jlt addr [, offset_reg] -``` - -##### JLE - Jump if Less or Equal - -```assembly -jle addr [, offset_reg] -``` - ### Arithmetic Instructions -#### ADD - Addition - -```assembly -add src1_reg, src2_reg, dest_reg -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **ADD** | `src1_reg, src2_reg, dest_reg` | Addition | +| **SUB** | `src1_reg, src2_reg, dest_reg` | Subtraction | +| **IADD** | `src_reg, imm [, dest_reg]` | Immediate addition | +| **ISUB** | `src_reg, imm [, dest_reg]` | Immediate subtraction | +| **INC** | `reg` | Increment register by 1 | +| **DEC** | `reg` | Decrement register by 1 | **Examples:** - -```assembly +```asm add rg0, rg1, rg2 ; rg2 = rg0 + rg1 -add rg1, rg2, acc ; acc = rg1 + rg2 -``` - -#### SUB - Subtraction - -```assembly -sub src1_reg, src2_reg, dest_reg -``` - -**Examples:** - -```assembly sub rg0, rg1, rg2 ; rg2 = rg0 - rg1 -sub acc, rg1, acc ; acc = acc - rg1 -``` - -#### IADD - Immediate Addition - -```assembly -iadd src_reg, imm [, dest_reg] -``` - -**Examples:** - -```assembly iadd rg0, 10 ; rg0 = rg0 + 10 -iadd rg0, 5, rg1 ; rg1 = rg0 + 5 -``` - -#### ISUB - Immediate Subtraction - -```assembly -isub src_reg, imm [, dest_reg] -``` - -**Examples:** - -```assembly -isub rg0, 7 ; rg0 = rg0 - 7 -isub rg0, 3, rg1 ; rg1 = rg0 - 3 -``` - -#### INC - Increment - -```assembly -inc reg -``` - -**Examples:** - -```assembly +// or using alternate syntax +addi rg0, 1 ; rg0 = rg0 + 1 inc rg0 ; rg0 = rg0 + 1 -inc spr ; Increment stack pointer ``` - -#### DEC - Decrement - -```assembly -dec reg -``` - -**Examples:** - -```assembly -dec rg0 ; rg0 = rg0 - 1 -dec rg1 ; Decrement rg1 -``` - ### Bitwise Operations -#### AND - Bitwise AND - -```assembly -and src1_reg, src2_reg, dest_reg -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **AND** | `src1_reg, src2_reg, dest_reg` | Bitwise AND | +| **OR** | `src1_reg, src2_reg, dest_reg` | Bitwise OR | +| **XOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XOR | +| **NOT** | `src_reg, dest_reg` | Bitwise NOT | +| **NAND** | `src1_reg, src2_reg, dest_reg` | Bitwise NAND | +| **NOR** | `src1_reg, src2_reg, dest_reg` | Bitwise NOR | +| **XNOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XNOR | **Examples:** - -```assembly +```dsa and rg0, rg1, rg2 ; rg2 = rg0 & rg1 -``` - -#### OR - Bitwise OR - -```assembly -or src1_reg, src2_reg, dest_reg -``` - -#### XOR - Bitwise XOR - -```assembly -xor src1_reg, src2_reg, dest_reg -``` - -#### NOT - Bitwise NOT - -```assembly -not src_reg, dest_reg -``` - -**Examples:** - -```assembly not rg0, rg1 ; rg1 = ~rg0 ``` - -#### NAND - Bitwise NAND - -```assembly -nand src1_reg, src2_reg, dest_reg -``` - -#### NOR - Bitwise NOR - -```assembly -nor src1_reg, src2_reg, dest_reg -``` - -#### XNOR - Bitwise XNOR - -```assembly -xnor src1_reg, src2_reg, dest_reg -``` - ### Shift Operations -#### SHL - Shift Left - -```assembly -shl reg, shift_amount -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **SHL** | `reg, shift_amount` | Shift left | +| **SHR** | `reg, shift_amount` | Shift right | **Examples:** - -```assembly +```dsa shl rg0, 2 ; Shift rg0 left by 2 bits -shl acc, 4 ; Shift accumulator left by 4 bits -``` - -#### SHR - Shift Right - -```assembly -shr reg, shift_amount -``` - -**Examples:** - -```assembly shr rg0, 3 ; Shift rg0 right by 3 bits ``` - ### Comparison and Control -#### CMP - Compare - -```assembly -cmp reg1, reg2 -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **CMP** | `reg1, reg2` | Compare registers and set flags | **Examples:** - -```assembly +```dsa cmp rg0, zero ; Compare rg0 with zero register cmp rg1, rg2 ; Compare rg1 with rg2 ``` - ### System Instructions -#### HLT - Halt - -```assembly -hlt -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **HLT** | - | Halt processor execution | +| **NOP** | - | No operation | +| **INT** | `interrupt_code` | Trigger interrupt | +| **IRT** | - | Return from interrupt | **Examples:** - -```assembly +```dsa hlt ; Stop processor execution -``` - -#### NOP - No Operation - -```assembly -nop -``` - -**Examples:** - -```assembly -nop ; Do nothing for one cycle -``` - -#### INT - Interrupt - -```assembly -int interrupt_code -``` - -**Examples:** - -```assembly int 0x21 ; Trigger interrupt 0x21 ``` - -#### IRT - Interrupt Return - -```assembly -irt -``` - -**Examples:** - -```assembly -irt ; Return from interrupt -``` - ## Pseudo-Instructions ### Data Definition -#### DB - Define Bytes - -```assembly -db name: value1 [, value2, ...] -``` +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **DB** | `name: value1 [, value2, ...]` | Define bytes | +| **DH** | `name: value1 [, value2, ...]` | Define half-words | +| **DW** | `name: value1 [, value2, ...]` | Define words | **Examples:** - -```assembly +```dsa db message: "Hello World", 0 -db values: 10, 20, 30, 0xFF -db fib_count: 10 -``` - -#### DH - Define Half-words - -```assembly -dh name: value1 [, value2, ...] -``` - -**Examples:** - -```assembly dh numbers: 1000, 2000, 3000 -dh coordinates: 0x1234, 0x5678 -``` - -#### DW - Define Words - -```assembly -dw name: value1 [, value2, ...] -``` - -**Examples:** - -```assembly dw stack: 0x10000 -dw display: 0x20000 -dw buffer: 0x8000, 0x9000 ``` - ### Memory Reservation -#### RESB - Reserve Bytes - -```assembly -resb name: size -``` +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **RESB** | `name: size` | Reserve bytes | +| **RESH** | `name: size` | Reserve half-words | +| **RESW** | `name: size` | Reserve words | **Examples:** - -```assembly +```dsa resb buffer: 256 ; Reserve 256 bytes -``` - -#### RESH - Reserve Half-words - -```assembly -resh name: size -``` - -**Examples:** - -```assembly resh array: 100 ; Reserve space for 100 half-words -``` - -#### RESW - Reserve Words - -```assembly -resw name: size -``` - -**Examples:** - -```assembly resw heap: 1024 ; Reserve space for 1024 words ``` - ### Stack Operations -#### PUSH - Push to Stack - -```assembly -push reg -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **PUSH** | `reg` | Push register value onto stack | +| **POP** | `reg` | Pop stack value into register | **Examples:** - -```assembly +```dsa push rg0 ; Push rg0 value onto stack -push pcx ; Push program counter -push ret ; Push return address -``` - -#### POP - Pop from Stack - -```assembly -pop reg -``` - -**Examples:** - -```assembly -pop rg0 ; Pop top stack value into rg0 pop ret ; Pop return address ``` - ### Memory Access Shortcuts -#### LWI - Load Word Immediate (Address) - -```assembly -lwi name, reg -``` +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **LWI** | `name, reg` | Load address into register | **Examples:** - -```assembly +```dsa lwi string, rg1 ; Load address of 'string' into rg1 -lwi buffer, rg0 ; Load address of 'buffer' into rg0 +``` + +### Function Control + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **CALL** | `namespace::function` | Call a function with automatic return address management | +| **RETURN** | - | Return from a function to the caller | + +**Examples:** +```dsa +call print::print ; Call the print function from the print namespace +return ; Return from the current function ``` ### Module System -#### INCLUDE - Include Module - -```assembly -include module_name "path" -``` +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **INCLUDE** | `module_name "path"` | Include module | **Examples:** - -```assembly -include print "../resources/dsa/print.dsa" -include fib "../resources/dsa/fib.dsa" -``` - -## Example Programs and libraries. ```dsa -// lib: -// print.dsa +include print "print.dsa" +include fib "fib.dsa" +``` +## Library Examples +### Multiplication Library (multiply.dsa) + +```dsa +// multiply.dsa // usage: // -// include print """ +// include multiply "" +// +// usage for multiply: +// push (arg1) +// push (arg0) +// call multiply::multiply +// pop (arg0) +// pop (arg1) + +multiply: + push bpr + mov spr, bpr + + ldw bpr, rg0, 8 // load op 1 + ldw bpr, rg1, 12 // load op 2 + + lli 0, acc // initialize accumulator + +start: + add acc, rg0, acc + dec rg1 + + cmp rg1, zero + jgt start + +end: + stw acc, bpr, 8 // store result for caller + mov bpr, spr + pop bpr + return +``` + +### Print Library (print.dsa) + +```dsa +// print.dsa +// usage: +// +// include print "" // // usage for print: // push (register containing address of string) -// push pcx -// jmp print::print +// call print::print +// pop zero // // usage for reset: -// push pcx -// jmp print::reset +// call print::reset dw display: 0x20000 dw current: 0x20000 -reset: - pop ret - ldw display, rg1 - stw rg1, current - jmp 4, ret - +// prints the given text to the screen. print: - pop ret // return address - pop rg0 // string - ldw current, rg1 + push bpr + mov spr, bpr -loop: - ldb rg0, acc - stb acc, rg1 + ldw bpr, rg0, 8 // get string address argument + ldw current, rg1 // get current display position - iadd rg0, 1 - iadd rg1, 1 +print_loop: + ldb rg0, acc + stb acc, rg1 + + iadd rg0, 1 + iadd rg1, 1 cmp acc, zero - jne loop + jne print_loop + jmp end - // return +// return end: - // set current to stw rg1, current - jmp 4, ret + + mov bpr, spr + pop bpr + return + +// resets the cursor position on the screen +reset: + push bpr + mov spr, bpr + ldw display, rg1 + stw rg1, current + mov bpr, spr + pop bpr + return ``` +### Example Program (main.dsa) ```dsa -// lib: -// fib.dsa -// this is a simple library to calculate the fibonacci sequence up to n, writing each value to the stack. - -fib_n: - pop ret // pops the return address from the stack - pop rg0 // pops the function arg (n) from the stack - - lli 0, rg1 - lli 1, rg2 - -start: - add rg1, rg2, acc - push rg1 - mov rg2, rg1 - mov acc, rg2 - - cmp rg0, zero - dec rg0 - - jgt start - jmp 4, ret -``` - -```dsa -include print "print.dsa" -include fib "fib.dsa" +include print "./print.dsa" dw stack: 0x10000 -db string: "An idiot admires complexity, a genius admires simplicity, -a physicist tries to make it simple, for an idiot anything the more complicated it is, -the more he will admire it, if you make something so clusterfucked he can't understand it he's -gonna think you're a god cause you made it so complicated nobody can understand it. -That's how they write journals in Academics, they try to make it so complicated people think you're a genius" +db string: "'To confuse your enemy, you must first confuse yourself' - Probably Sun Tzu." init: - ldw stack, bpr - mov bpr, spr + // set up a stack. + ldw stack, bpr + mov bpr, spr start: - lwi string, rg1 - - // push variables - push rg1 // string address. - push pcx // return address. - - // call - jmp print::print - - - lli 25, rg0 - push rg0 - push pcx - jmp fib::fib_n - - hlt -``` - - + lwi string, rg1 + // push string address argument + push rg1 + // call print function + call print::print + // clean up stack + pop rg1 + hlt +``` \ No newline at end of file