From 71d79d0a6d6ea1e593820f81a944ed56d04c4637 Mon Sep 17 00:00:00 2001 From: Diego Lopez <2109094@upy.edu.mx> Date: Mon, 9 Mar 2026 16:53:27 -0600 Subject: [PATCH] blog post 2 --- blog-post-2.md | 136 +++++++++++++++++++++++ calling-convention/Output-explanation.md | 3 +- 2 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 blog-post-2.md diff --git a/blog-post-2.md b/blog-post-2.md new file mode 100644 index 0000000..4cebb35 --- /dev/null +++ b/blog-post-2.md @@ -0,0 +1,136 @@ +# Blog Entry #2 — Registers, Addressing Modes & Type Size Modifiers + +In this second entry I will cover three fundamental concepts of the +Spider Virtual Machine: the register table, addressing modes, and +type size modifiers. These three systems work together to define how +every single instruction in Spider operates. + +--- + +## Registers + +The Spider VM provides two categories of registers. + +**General Purpose Registers (16 total)** are directly accessible from +instructions using addressing modes. They can hold either integers or +floats depending on the instruction being executed. + +The 16 GP registers have defined roles by convention: + +- `RA` — First argument and return value of a function +- `RB`, `RC`, `RD` — Second, third and fourth arguments +- `RX`, `RY` — Free auxiliary registers with no rules +- `R0`–`R3` — Caller-saved: the called function may overwrite them +- `R4`–`R7` — Callee-saved: the called function must restore them +- `R8`, `R9` — Fifth and sixth function arguments + +**System Registers (8 total)** cannot be accessed directly by addressing +modes. They require dedicated instructions to read or modify them, and +they are always integers. + +The most important system registers are: + +- `RF` — Flag Register: holds the full state of the VM in 64 bits +- `RI` — Instruction Register: points to the current instruction (program counter) +- `RS` — Stack Register: tracks the current top of the stack +- `RZ` — Stack Base Register: base reference for the current function frame +- `RE` — Exception Register: holds the address of the active exception handler +- `RV` — Interrupt Vector Register: used for both internal and external interrupts +- `RM` — Memory Register: total RAM available to the VM + +One of Spider's core design decisions is to prioritize registers over +the stack. Since registers are always available and fast to access, +a well-written Spider program can run with minimal stack usage. +This is especially important on constrained hardware like the ATmega328p, +which only has 2KB of RAM. + +--- + +## Addressing Modes + +Each instruction in Spider operates on parameters. An addressing mode +defines **how to interpret** those parameters. The same instruction can +behave very differently depending on the mode. + +Spider has 8 addressing modes: + +| Mode | Syntax | Meaning | +|-----------|-------------------|------------------------------------------------------| +| Implied | (none) | No parameter needed, operand is implicit | +| Immediate | `42i` | The value is a literal constant | +| Absolute | `0x1000i` | The value is a fixed memory address | +| Register | `RA` | The value is stored in a register | +| Indirect | `[0x1000i]` | Go to that address and use what's stored there | +| Pointer | `[RA]` | The register holds a memory address, follow it | +| Indexed | `[RA + 8i]` | Base register plus a constant offset | +| Scaled | `[RA + RB * 4i]` | Base register plus scaled index register | +| Displaced | `[RA + RB*4i+2i]` | Full address calculation with two registers | + +Addressing modes are encoded in 5 bits inside each 2-byte instruction. +When an instruction has two parameters, those 5 bits are split: 2 bits +for the first parameter and 3 bits for the second. + +A modifier suffix is used in assembly syntax to specify the mode explicitly: +`.imp`, `.imm`, `.abs`, `.reg`, `.ind`, `.ptr`, `.idx`, `.sca`, `.dis` + +For example: +``` +MOV.reg RA, RB ; move value from RB into RA using registers +MOV.ptr RA, [RB] ; move value from address stored in RB into RA +MOV.idx RA, [RB + 8i] ; move value from address RB+8 into RA +``` + +--- + +## Type Size Modifiers + +Every instruction in Spider also carries a **type size modifier** encoded +in the last 2 bits of the 2-byte instruction header. This tells the VM +how many bytes to read or write when executing the instruction. + +| Type | Modifier | Size | +|--------|----------|--------| +| Byte | `.B` | 1 byte | +| Short | `.S` | 2 bytes| +| Int | `.I` | 4 bytes| +| Long | `.L` | 8 bytes| +| Float | `.F` | 4 bytes| +| Double | `.D` | 8 bytes| + +The type modifier applies to the **entire instruction**, meaning both +operands must be congruent. You cannot mix sizes in a single instruction. + +This system is directly tied to Spider's philosophy of **strong typing**: +the programmer always knows exactly how much memory an operation consumes. +There are no hidden conversions or surprises. + +Two important behaviors to understand: + +**Reading a smaller size** ignores the top bits of the value. For example, +reading a register containing `0x12345678` with `.B` gives you `0x78`. + +**Writing a smaller size** only modifies the lower bytes and leaves the +top bits untouched. Writing `0xAB` with `.B` into that same register +gives you `0x123456AB`. + +A complete instruction combining all three systems looks like this: +``` +MOV.I.reg RA, RB ; move a 4-byte integer from RB into RA +MOV.B.ptr RA, [RB] ; move 1 byte from the address in RB into RA +ADD.L.idx RA, [RB + 8i] ; add 8-byte value at address RB+8 into RA +``` + +--- + +## How these three systems connect + +These three concepts are not independent. Every instruction in Spider +uses all three simultaneously: + +- The **op code** (9 bits) says what to do +- The **addressing mode** (5 bits) says where the data is +- The **type modifier** (2 bits) says how big the data is + +Together they fit in exactly 2 bytes per instruction, followed by the +actual parameter data. This compact design is what makes Spider efficient +enough to run on microcontrollers with very limited memory. \ No newline at end of file diff --git a/calling-convention/Output-explanation.md b/calling-convention/Output-explanation.md index d89aaa8..39a9292 100644 --- a/calling-convention/Output-explanation.md +++ b/calling-convention/Output-explanation.md @@ -37,7 +37,7 @@ and the result value `42` is successfully collected from `RA`. **Function signature:** `result = func(a, b, c, d, e, f, g, h)` -**Output** +**Output:** ``` ===== TEST 2: 8 arguments, some on the stack ===== === State after do_function_call === @@ -67,7 +67,6 @@ all stack entries are cleaned and the result `99` is collected from `RA`. **Output:** ``` - ===== TEST 3: Boolean arguments ===== === State after do_function_call === Registers used: ['RA', 'RB']