Subleq
A small SUBLEQ one-instruction-set computer (OISC) authored for emulators.org and running in the browser. Every instruction is a triple (A, B, C): it subtracts Mem[A] from Mem[B] and branches to C when the result is less than or equal to zero. A negative address selects character I/O. It boots printing "Hello, world!" and plugs into the shared debugger, so you can single-step the one instruction, set breakpoints on the instruction pointer, and watch memory change.
Runs on: Web browser
Subleq Online Emulator
Play Subleq using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Hello, world! | Subleq | Subleq (OISC) | open | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
subleq is a self-contained one-instruction computer authored for this site. Vendor the two source files and drive the machine from your own loop; the core never touches the DOM, so the debugger can pause, step and breakpoint it:
var vm = new SubleqVM({ onOutput: putChar, onInput: getChar });
vm.load(SubleqVM.printProgram('Hello, world!\n')); // a ready-to-run image
while (vm.step()) {} // step() = one instruction
The machine is a plain object. Everything the debugger needs is a live field. There is no wasm heap to reach into:
| Member | Kind | What it does |
|---|---|---|
vm.step() | method | Execute exactly one SUBLEQ instruction (the single-step primitive). Returns false once halted or blocked on input. |
vm.ip | field | The instruction pointer (a word index). Halts when it goes negative. |
vm.mem | field | The word-addressed memory: a plain array of signed integers. |
vm.rd(a) / vm.wr(a,v) | method | Side-effect-free read / write of one word, what the debugger's hex view and watchpoints call. |
SubleqVM.printProgram(s) | static | Assemble a self-contained "print this string" image (one OUT per character + a halt). |
Because the CPU and memory are ordinary JavaScript, breakpoints and watchpoints are host-side checks around vm.step() and vm.wr() - no changes to the core.
Debugger integration
The boot shim publishes window.EMU_BOOT with a full transport: pause / resume / isPaused, stepInsn(n) (one instruction) and step(n) (a burst), reset, plus breakpoints (a Set of instruction-pointer values the loop checks before each step) and watchpoints (a Set of memory addresses, checked inside vm.wr). A new CPU decoder - /debugger/src/cpus/subleq.js - disassembles each triple as one instruction: subleq A, B, C, or OUT A / IN B when an operand is -1. It reads the true signed words off EMU_BOOT.vm.mem, because the shared views hand decoders a byte-masked reader that would truncate a word operand.
Architecture
SUBLEQ (SUBtract and branch if Less-than or EQual to zero) is the canonical one-instruction machine. There is a single instruction, so there is no opcode. Every three consecutive words are an instruction:
- (A, B, C) -
Mem[B] = Mem[B] - Mem[A]; if the result is<= 0the instruction pointer jumps toC, otherwise it falls through to the next triple. - A == -1 - read one character from the input stream into
Mem[B]. - B == -1 - write
Mem[A]out as a character. - Execution halts when the instruction pointer becomes negative (programs branch to
-1to stop).
Despite having one instruction, SUBLEQ is Turing-complete: subtraction plus a conditional branch is enough to synthesise moves, adds, copies and loops. The bundled "Hello, world!" image emits each character with its own OUT instruction, then zeroes a scratch cell and branches to -1 to halt.