We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
16×4 bits, ∞ bytes
16×4 bits, ∞ bytes, or simply 64 bits, ∞ bytes, or even UnASM-64, is designed by PSTF. This is the largest CPU until July 2026 if we don't count ∞ bits, ℵ0 Bytes by the same author.
It captures the raw, minimalist spirit of ASM while embracing modern 64-bit parallelism.
Architecture
- This programming language is designed for a 4-core CPU, so we label the four cores as zero, one, two, and three.
- There are 32 64-bit registers, where R0 is a reserved register, R29 is the stack pointer, and R30 is the link register.
- Each core has its own set of flag registers. They are: the zero flag (set to 1 if the value is 0), the sign flag (set to 1 for negative numbers), the carry flag (set to 1 when there's a carry or borrow), and the overflow flag (set to 1 if the result goes beyond the 64-bit signed calculation range).
- Each core is also equipped with a program counter, 64-bit.
- The encoding defaults to UTF-32LE.
Memory
- The memory is made up of infinite 64-bit cells.
- No protection rings, no paging constraints in the spec—just raw [address] access.
- Aligned access is recommended, but unaligned is permitted (with a performance penalty).
- Synchronization: Atomic Compare-And-Swap (CAS) and explicit Memory Barrier (MBAR) ensure safe concurrency.
Instruction Set
Syntax: OPCODE destination, source1, source2.
Immediate numbers are written after a hashtag.
Registers are written with Rx.
Memory addresses are written within brackets.
Data Movement
MOV Rd, k: Set the target register to k, where k can be another register or an immediate value. LOAD Rd, [Rs + offset]: Assign Rd to the data at [Rs + offset], where Rs and Rd are both registers, and offset is an immediate value. STORE Rs, [Rd + offset]: Assign the data at [Rd + offset] to Rs, where Rs and Rd are both registers, and offset is an immediate value. PUSH Rs: Move the stack pointer down, then store Rs at the top of the stack. POP Rs: Load the top value of the stack into Rd, then move the stack pointer up.
Arithmetic and Logical
ADD Rd, Rs, k: Set Rd to the sum of Rs and k, where both Rd and Rs are registers, and k can be a register or an immediate value. SUB Rd, Rs, k: Set Rd to the difference of Rs and k, where both Rd and Rs are registers, and k can be a register or an immediate value. MUL Rd, Rs, k: Set Rd to the product of Rs and k, where both Rd and Rs are registers, and k can be a register or an immediate value. DIV Rd, Rs, k: Set Rd to the quotient of Rs and k, where both Rd and Rs are registers, and k can be a register or an immediate value. MOD Rd, Rs, k: Set Rd to the remainder of Rs and k, where both Rd and Rs are registers, and k can be a register or an immediate value. AND, OR, NOT, XOR: Bitwise operations. SHL, SHR, SAR: From left to right, they are left shift (multiply by 2 to the power of k, where k is an immediate value or a register), logical right shift, and arithmetic right shift (divide by 2 to the power of k, discarding the remainder, where k is an immediate value or a register). CMP Rs1, Rs2: Calculate the difference between Rs1 and Rs2 but don't store it, just update the flags register.
Control Flow
JMP label: Directly jump to label, where the label is a program label or an address. JEQ, JNE, JGT, JNG, JLT, JNL: Conditioned jump based on flags. CALL label: Push the value of the program counter plus 1 onto the stack, then jump to the place indicated by the label. RET : Restore the value of the program counter from the stack and jump to the address corresponding to that value. HLT : Stop the current thread of the kernel and set the kernel's status to 'idle'.
I/O
WRITE Rs: Output the lower 21 bits of Rs as characters to the console. Surrogate characters and invalid code points will be displayed as '�' (code point: 0xFFFD). READ Rs: Clear Rs, then input a Unicode character into Rs.
Multicore Operations
FORK x, label: Fork the program from the label to run on core x. If that core is already running, shut it down and reset it to the state at the label. The calling core then continues immediately. JOIN x: Makes the 'current kernel' of other kernels stop until kernel x executes the HALT command before continuing. CAS [Rd], Rs, Rt: Compare the value at address Rd with Rs. If they are equal, write the value of Rt into address Rd and set Z to 1. Otherwise, load the value at address Rd into Rt and set Z to 0. MBAR : Memory Barrier. Ensures all prior loads/stores are globally visible before continuing.
Assembly Directives
.text: Code. .data: Data. .word v1, ...: Store 64-bit data. .byte v1, ...: Store 8-bit data. .ucs4 "string": Stores the string as UTF-32 (UCS-4) codepoints, null-terminated. Supports any Unicode literal (e.g., "你好 😊"). label: : Defines a symbol for jumps/loads.
Computational Class
A minimal Turing machine requires:
- Unbounded storage → 64-bit memory provides 2⁶⁴ bytes, practically infinite. The LOAD/STORE instructions can access any cell.
- Conditional branching → CMP + JZ/JNZ execute arbitrary code based on state.
- Elementary operations → ADD, SUB, MOV modify state.
Because 16×4 bits, ∞ bytes can implement a Minsky machine (using registers as counters, and SUB + JZ for zero-testing), it is rigorously Turing-complete.
Example Program
Unicode Chaos of 4 cores
.data
msg0: .ucs4 "Hello from Core 0! 🌍\n"
msg1: .ucs4 "来自内核一的问候! ⚡\n"
newline: .ucs4 "\n"
.text
; ---------- Core 0: String Printer ----------
:core0_entry
MOV R1, #msg0 ; Load pointer to string
:loop0
LOAD R2, [R1] ; Load next codepoint
CMP R2, #0 ; Check for null terminator
JEQ :done0
WRITE R2 ; Output the Unicode char
ADD R1, R1, #4 ; Move to next 32-bit codepoint
JMP :loop0
:done0
HALT
; ---------- Core 1: Another String ----------
:core1_entry
MOV R1, #msg1
:loop1
LOAD R2, [R1]
CMP R2, #0
JEQ :done1
WRITE R2
ADD R1, R1, #4
JMP :loop1
:done1
HALT
; ---------- Core 2: Numeric Counter (1 to 10) ----------
:core2_entry
MOV R3, #1 ; Counter
:loop2
CMP R3, #11 ; Check > 10
JGT :done2
MOV R4, #'0' ; Convert to ASCII (basic Unicode)
ADD R4, R4, R3
WRITE R4 ; Print number
MOV R4, #' ' ; Print space
WRITE R4
ADD R3, R3, #1
JMP :loop2
:done2
MOV R4, #'\n'
WRITE R4
HALT
; ---------- Core 3: Random Character Showcase ----------
:core3_entry
; Print: 😊 🚀 ❤️ ⒇ ゑ 钟
MOV R1, #0x1F60A ; 😊
WRITE R1
MOV R1, #0x20
WRITE R1 ; space
MOV R1, #0x1F680 ; 🚀
WRITE R1
MOV R1, #0x20
WRITE R1
MOV R1, #0x2764 ; ❤️ (combining may vary, but codepoint works)
WRITE R1
MOV R1, #0x20
WRITE R1
MOV R1, #0x2487 ; ⒇
WRITE R1
MOV R1, #0x20
WRITE R1 ; space
MOV R1, #0x3091 ; ゑ
WRITE R1
MOV R1, #0x20
WRITE R1
MOV R1, #0x949f ; 钟
MOV R1, #'\n'
WRITE R1
HALT
; ---------- Main Core (Boot Core) ----------
:start
; Fork all cores to their entries
FORK #1, :core1_entry
FORK #2, :core2_entry
FORK #3, :core3_entry
; Core 0 runs its own task here
CALL :core0_entry ; Wait for Core 0 to finish its routine
; Now wait for all other cores to finish
JOIN #1
JOIN #2
JOIN #3
; Print a final global message
MOV R1, #'\n'
WRITE R1
MOV R1, #'A'
WRITE R1
MOV R1, #'l'
WRITE R1
MOV R1, #'l'
WRITE R1
MOV R1, #' '
WRITE R1
MOV R1, #'d'
WRITE R1
MOV R1, #'o'
WRITE R1
MOV R1, #'n'
WRITE R1
MOV R1, #'e'
WRITE R1
MOV R1, #'!'
WRITE R1
MOV R1, #'\n'
WRITE R1
HALT ; Main core shuts down. System halts.