MITS ISA Documentation

Multi Instruction Table Set

A compact, minimal assembly language designed for simplicity. MITS features intuitive string handling, ROM-based static data storage, powerful control flow constructs, and a unique 3-letter variable naming convention that enforces concise, readable code.

Developed and maintained by syntaxMORG0

Source: GitHub Repository


Table of Contents


Overview

MITS (Multi Instruction Table Set) is a minimal, stack-less assembly language designed for simplicity and clarity. Unlike traditional assembly languages with complex register management and memory addressing, MITS provides a clean, intuitive interface for low-level programming while maintaining powerful functionality.

Key Features:

Whether you're learning assembly concepts, building educational tools, or creating compact utilities, MITS provides an accessible yet powerful platform for low-level programming.


Getting Started

Getting up and running with MITS is straightforward. The toolchain consists of a compiler and interpreter, both built from C source code using standard make utilities.

Building the Tools

Clone and build from source at syntaxMORG0/MITS:

make              # build compiler and interpreter
make clean        # remove build artifacts

Running MITS Programs

Once built, use the ./mits launcher to execute your .s assembly files. The interpreter processes your code line-by-line, managing registers, executing instructions, and handling I/O operations.

Basic execution:

# With ROM data file (optional)
./mits program.s data.rom

# Without ROM data file (data.rom is optional)
./mits program.s

Note: The ROM file is completely optional. If your program doesn't use rom= lookups, you can omit it entirely.

ROM Files (Optional)

ROM (Read-Only Memory) files provide a way to store static configuration data, constants, and lookup tables separate from your program logic. This separation of data and code makes programs more maintainable and allows you to change data without recompiling.

ROM files use a simple key-value format with # for comments. Programs can run perfectly fine without ROM files - they're only needed if you use rom= lookups in your code.

Format:

# String values
name="John"
title="MITS"

# Numeric values
count=42
version=100

Access in program: mov dest, rom=key

File Extensions


Language Basics

Program Structure

Variable Naming Rules

The 3-Letter Rule: ALL variables in MITS must be exactly 3 letters (a-z, A-Z only). This unique constraint enforces concise, memorable variable names and creates a consistent coding style across all MITS programs.

Why 3 letters? This limitation encourages thoughtful naming (like msg for message, cnt for count, idx for index) while keeping code compact and readable. It's similar to how assembly traditionally uses short register names, but with semantic meaning.

Valid names: abc, xyz, msg, tmp, ret, num, str, val

Invalid names: ab (too short), abcd (too long), a1b (contains digit), my_var (too long, has underscore)

ERROR: Using invalid variable names will cause immediate runtime errors with a descriptive message.

Data Types

Type Created By Characteristics
NUMBER mov, arithmetic, rdl -i 64-bit signed integer
STRING char, rdl, conversions Text data (max 511 chars)
HEX hex= conversion Byte array

String Literals

Enclosed in double quotes: "hello"

Maximum length: 511 characters

Comments

Use semicolons for comments:

; Full line comment
mov abc, 10    ; Inline comment

ROM Data Storage

ROM files are optional and store static data.

Format:

# Comments use # in ROM files
name="John"
version=100

Access: mov dest, rom=key


Core Instructions

mov dest, src

Move value into register.

mov abc, 10           ; numeric literal
mov def, abc          ; copy from register
mov ghi, abc + def    ; arithmetic result
mov jkl, rom=count    ; from ROM
mov mno, code=1       ; exit code

char dest, "string"

Store string literal.

char msg, "hello world"

vga value

Output to stdout. Format depends on type:

mov num, 42
vga num               ; outputs: 42

char msg, "hello"
vga msg               ; outputs: hello

exec

exec register - Execute exit code:

mov ext, code=0
exec ext              ; exit with code 0

exec sys=help - List all instructions:

exec sys=help

exec function, args... - Call user function:

exec add, 10, 20

Data Conversions

hex= - String to Hex

Convert STRING to HEX bytes:

char msg, "MITS"
mov hex, hex=msg
vga hex               ; outputs: 4d 49 54 53

b31 - Hex to String (ANSI)

Convert HEX back to STRING:

char msg, "hello"
mov h1, hex=msg
mov h2, b31 h1
vga h2                ; outputs: hello

i32 / b32 - Hex to Integer

Convert HEX bytes to integer:

char msg, "MITS"
mov hex, hex=msg
mov num, i32 hex
vga num               ; outputs: 1296651347

c26 - To Character Data

Convert number or hex to string:

mov num, 12345
mov txt, c26 num
vga txt               ; outputs: 12345

flt - Floating Point

Convert integer to float representation:

mov num, 98765
mov flt, flt num
vga flt               ; outputs: 98765.00

UTF - UTF-8 Conversion

Convert to UTF-8 format:

char msg, "UTF-8 Text"
mov utf, UTF msg
vga utf               ; outputs: UTF-8 Text

rom= - From ROM

Load value from ROM storage:

mov val, rom=key

code= - Exit Code

Load an exit code:

mov ext, code=0       ; success
mov err, code=1       ; error

Arithmetic Operations

addr dest, expr

ADD numbers or concatenate HEX:

; Addition
mov aaa, 10
mov bbb, 20
addr ccc, aaa + bbb   ; ccc = 30

; HEX concatenation
mov h1, hex=msg1
mov h2, hex=msg2
addr res, h1 + h2     ; merged bytes

subr dest, a - b

SUBTRACT right from left:

mov xxx, 100
mov yyy, 35
subr zzz, xxx - yyy   ; zzz = 65

mul dest, a * b

MULTIPLY two numbers:

mov naa, 12
mov nbb, 5
mul prd, naa * nbb    ; prd = 60

div dest, a / b

INTEGER DIVISION:

mov num, 20
mov den, 3
div qot, num / den    ; qot = 6

mod dest, a % b

MODULO (remainder):

mov aaa, 20
mov bbb, 3
mod rem, aaa % bbb    ; rem = 2

sda dest, values...

SUM all values:

sda sum, 10, 20, 30   ; sum = 60

mov aaa, 5
mov bbb, 10
sda tot, aaa, bbb     ; tot = 15

Input and Output

rdl - Read Line

Read input from stdin with optional type conversion.

rdl -i dest - Read as integer:

rdl -i num            ; converts input to NUMBER

rdl -f dest - Read as float:

rdl -f flt            ; stores as formatted string "X.XX"

rdl -s dest - Read as string (explicit):

rdl -s str            ; reads as STRING

rdl dest - Read as string (default):

rdl txt               ; default: STRING type

Complete Input Example

_start:
    char prm, "Enter number: "
    vga prm
    rdl -i num
    vga num

    char pm2, "Enter float: "
    vga pm2
    rdl -f flt
    vga flt

    char pm3, "Enter text: "
    vga pm3
    rdl txt
    vga txt
    
    mov ext, code=0
    exec ext

Debugging - read Instruction

The read instruction provides inspection and debugging capabilities.

read -lt -a adr

List all registers:

read -lt -a adr       ; shows all defined registers

read -lt adr <register>

Show specific register details:

read -lt adr msg      ; detailed info about 'msg'

read -lt -a rom <file>

List all ROM entries:

read -lt -a rom data.rom

read -lt rom <file> <key>

Show specific ROM entry:

read -lt rom data.rom name

Hex Dump Mode (-hxd flag)

Add -hxd to show hexadecimal representation:

read -lt -a -hxd adr          ; all registers with hex
read -lt -hxd adr msg         ; specific register with hex
read -lt -a -hxd rom data.rom ; ROM entries with hex

Debugging Example

_start:
    mov aaa, 100
    char bbb, "test"
    mov ccc, hex=bbb
    
    ; List all registers
    read -lt -a adr
    
    ; Inspect specific register
    read -lt adr ccc
    
    ; Show hex dump
    read -lt -hxd adr bbb
    
    mov ext, code=0
    exec ext

Control Flow

for mov index, start, end, exec: ... end

Loop from start to end (inclusive):

mov cnt, 3
for mov idx, 0, cnt, exec:
    vga idx           ; outputs: 0, 1, 2, 3
end

cond condition, exec: ... end

Conditional execution. Supports: < > <= >= == !=

mov xxx, 5
mov yyy, 10

cond xxx < yyy, exec:
    vga 1             ; executes if xxx < yyy
end

cond xxx == yyy, exec:
    vga 2
else
    vga 3             ; else clause
end

Functions and Modules

def name, ARGUMENTS, exec: ... end

Define a function:

def add, ARGUMENTS, exec:
    sda ret, ARGUMENTS
end

_start:
    exec add, 10, 20
    vga ret           ; outputs: 30
    mov ext, code=0
    exec ext

req ftype="type", "file"

Import external files. Types: "rom" or "asm"

req ftype="rom", "data.rom"
req ftype="asm", "helpers.s"

Type System

Type Conversion Summary

Conversion Usage Result Type
hex= STRING → HEX HEX
b31 HEX → STRING STRING
i32 / b32 HEX → NUMBER NUMBER
c26 NUMBER → STRING STRING
flt NUMBER → FLOAT STRING STRING
UTF STRING → UTF-8 STRING

Error Handling


Examples

Basic Examples

Hello World

_start:
    char msg, "Hello, MITS!"
    vga msg
    mov ext, code=0
    exec ext

Basic Arithmetic

_start:
    mov aaa, 100
    mov bbb, 50
    addr ccc, aaa + bbb
    vga ccc           ; outputs: 150
    mov ext, code=0
    exec ext

User Input (Integer)

_start:
    char prm, "Enter a number: "
    vga prm
    rdl -i num
    vga num
    mov ext, code=0
    exec ext

User Input (Float)

_start:
    char prm, "Enter decimal: "
    vga prm
    rdl -f flt
    vga flt           ; formatted as "X.XX"
    mov ext, code=0
    exec ext

User Input (String)

_start:
    char ask, "Enter name: "
    vga ask
    rdl nam
    vga nam
    mov ext, code=0
    exec ext

Conversions

_start:
    ; String to hex
    char msg, "MITS"
    mov hex, hex=msg
    vga hex           ; 4d 49 54 53
    
    ; Hex to string
    mov str, b31 hex
    vga str           ; MITS
    
    ; Hex to integer
    mov num, i32 hex
    vga num           ; 1296651347
    
    ; Number to string
    mov val, 12345
    mov txt, c26 val
    vga txt           ; 12345
    
    ; Float representation
    mov flt, flt val
    vga flt           ; 12345.00
    
    mov ext, code=0
    exec ext

ROM Data Usage

; data.rom:
; name="MITS"
; version=100

_start:
    mov nam, rom=name
    vga nam
    
    mov ver, rom=version
    vga ver
    
    mov ext, code=0
    exec ext

Debugging with read

_start:
    mov aaa, 100
    char bbb, "test"
    mov ccc, hex=bbb
    
    ; List all registers
    read -lt -a adr
    
    ; Inspect specific
    read -lt adr ccc
    
    ; Hex dump
    read -lt -hxd adr bbb
    
    mov ext, code=0
    exec ext

Functions

def add, ARGUMENTS, exec:
    sda ret, ARGUMENTS
end

_start:
    exec add, 10, 20, 30
    vga ret           ; outputs: 60
    mov ext, code=0
    exec ext

Control Flow

_start:
    mov xxx, 5
    mov yyy, 10
    
    cond xxx < yyy, exec:
        char msg, "xxx is smaller"
        vga msg
    end
    
    for mov idx, 0, 3, exec:
        vga idx       ; outputs: 0, 1, 2, 3
    end
    
    mov ext, code=0
    exec ext

Complete Program

_start:
    ; Greeting
    char wel, "Welcome to MITS!"
    vga wel
    
    ; Get name
    char prm, "Enter your name: "
    vga prm
    rdl nam
    
    ; Echo name
    char msg, "Hello, "
    vga msg
    vga nam
    
    ; Get age
    char ag1, "Enter age: "
    vga ag1
    rdl -i age
    
    ; Calculate years to 100
    mov hun, 100
    subr rem, hun - age
    
    char ag2, "Years to 100: "
    vga ag2
    vga rem
    
    ; Exit
    mov ext, code=0
    exec ext

Libraries

MITS can be extended with external libraries. Below are examples of how to use different library implementations:

WebAssembly (WASM)

MITS supports building interactive web applications using WebAssembly. The wasm instruction allows you to create pages, define HTML elements, embed scripts (JavaScript and C), and serve them over HTTP.

Quick Start
_start:
    req ftype="wasm", lib.webasm
    mov home, wasm -np page="home"
    wasm -op 8000 -ap page="home"

This loads the WebAssembly library, creates a page, and starts a web server on port 8000.

WebAssembly Instruction Flags
-np (New Page)

Purpose: Creates a new page container for organizing HTML elements.

Syntax: wasm -np page="pagename"

Parameters:

  • page - String identifier for the page (e.g., "home", "about", "dashboard")

Example:

mov home, wasm -np page="home"
mov about, wasm -np page="about"
-ne (New Element)

Purpose: Creates an HTML DOM element with configurable properties.

Syntax: wasm -ne type="tagname" [txt="content"] [id="identifier"] [class="classname"] [style="css"]

Parameters:

  • type (required) - HTML tag name (h1, h2, p, span, div, button, input, form, etc.)
  • txt (optional) - Text content or placeholder
  • id (optional) - Unique identifier for CSS/JavaScript targeting
  • class (optional) - CSS class(es) for styling
  • style (optional) - Inline CSS rules

Available Element Types:

  • Headings: h1, h2, h3, h4, h5, h6
  • Text: p, span, strong, em, code, pre
  • Forms: form, input, button, textarea, label, select, fieldset
  • Containers: div, section, article, header, footer, nav, main, aside
  • Media: img, a, video, audio
  • Tables/Lists: table, thead, tbody, tr, th, td, ul, ol, li, dl

Example:

mov title, wasm -ne type="h1" txt="Welcome!" id="main-title" class="hero"
mov btn, wasm -ne type="button" txt="Click Me" id="cta-btn" class="btn-primary"
mov form, wasm -ne type="form" id="contact-form"
-ns (New Script)

Purpose: Embeds executable code (JavaScript for frontend, C/Clang for backend).

Syntax: wasm -ns ftype="javascript|clang" id="script_id" exec => { /* code */ }

Parameters:

  • ftype (required) - Script type: "javascript" (client-side) or "clang" (server-side C)
  • id (required) - Script identifier
  • exec => {...} (required) - Code block
  • devlabel (optional) - Documentation comment, ignored at runtime

Example:

; Client-side JavaScript
wasm -ns ftype="javascript" id="click-handler" exec => {
    document.getElementById("btn").onclick = function() {
        alert("Button clicked!");
    };
}

; Server-side C backend
wasm -ns ftype="clang" id="backend" exec => {
    #include <stdio.h>
    void process(char *data) {
        printf("Processing: %s\n", data);
    }
}
-ae (Attach Element)

Purpose: Associates an element or script with a page for rendering/execution.

Syntax: wasm -ae id="element_or_script_id" page="page_name"

Parameters:

  • id (required) - Identifier of the element or script to attach
  • page (required) - Target page name

Note: An element or script can be attached to multiple pages. Elements created with -ne and scripts with -ns must be attached to be rendered or executed.

Example:

mov title, wasm -ne type="h1" txt="Home" id="title"
mov btn, wasm -ne type="button" txt="Submit" id="btn"
mov home, wasm -np page="home"

wasm -ae id="title" page="home"
wasm -ae id="btn" page="home"
-op (Open Port) & -ap (Active Page)

Purpose: Starts the web server and designates the entry page.

Syntax: wasm -op port_number -ap page="page_name"

Parameters:

  • port (required) - Network port number (typically 8000-9999 for development, 80 for production)
  • -ap page (optional) - Sets which page is served as the root/home page

Behavior: Runs the web server and automatically builds the webpage from all attached elements and scripts. The server is ready to accept connections on localhost:port.

Example:

wasm -op 8000 -ap page="home"        ; Development on port 8000
wasm -op 3000 -ap page="dashboard"   ; Dashboard on port 3000
wasm -op 80 -ap page="public"        ; Production on port 80
Execution Model

When you run a MITS script with WebAssembly instructions:

  1. Load library: req ftype="wasm" initializes the WebAssembly runtime
  2. Define structure: Use -np to create pages, -ne to create elements, -ns to register scripts
  3. Organize: Use -ae to attach elements and scripts to pages
  4. Serve: Run wasm -op PORT -ap page="NAME" to start the web server
  5. Generated HTML: The interpreter generates complete HTML5 from your element definitions and serves it on the specified port
  6. JavaScript execution: JavaScript code blocks execute in the browser when the page loads
  7. C backend: Clang code blocks are compiled and executed server-side for data processing
Complete WebAssembly Example
_start:
    req ftype="wasm", lib.webasm

    ; Create pages
    mov home, wasm -np page="home"
    mov about, wasm -np page="about"

    ; Create elements
    mov title, wasm -ne type="h1" txt="My Website" id="title" class="header"
    mov desc, wasm -ne type="p" txt="Welcome to MITS WebAssembly!" id="desc"
    mov form, wasm -ne type="form" id="contact" class="form"
    mov name, wasm -ne type="input" txt="Name" id="name-field" class="input"
    mov email, wasm -ne type="input" txt="Email" id="email-field" class="input"
    mov btn, wasm -ne type="button" txt="Submit" id="submit-btn" class="btn-primary"

    ; Attach to home page
    wasm -ae id="title" page="home"
    wasm -ae id="desc" page="home"
    wasm -ae id="contact" page="home"
    wasm -ae id="name-field" page="home"
    wasm -ae id="email-field" page="home"
    wasm -ae id="submit-btn" page="home"

    ; Create interactive script
    wasm -ns ftype="javascript" id="form-handler" exec => {
        document.getElementById("submit-btn").addEventListener("click", function() {
            let name = document.getElementById("name-field").value;
            let email = document.getElementById("email-field").value;
            alert("Form received: " + name + " (" + email + ")");
        });
    }

    ; Backend processor
    wasm -ns ftype="clang" id="processor" exec => {
        #include <stdio.h>
        void validate_email(char *email) {
            if (email[0] != '\0') {
                printf("Email is valid\n");
            }
        }
    }

    ; Attach scripts
    wasm -ae id="form-handler" page="home"
    wasm -ae id="processor" page="home"

    ; Start web server on port 8000
    wasm -op 8000 -ap page="home"