beginner guide

Core War Instruction Set

This guide explains the instruction set in your visualizer in plain English. It is written for somebody new to Core War, so the goal is not just to list the commands, but to explain what each one is for, when you would use it, and what common beginner mistakes to avoid.

Big idea A warrior is just a tiny program that lives in circular memory and tries to outlast the other warrior.
Most important rule Most instructions read from A and write to B.
DAT warning If a process executes DAT, that process dies.
Newbie shortcut Learn MOV, JMP, DJN, SEQ, and SPL first. That gets you very far.

How a line is built

A typical line looks like this:

ADD.F  source   target

ADD is the opcode, .F is the modifier, source is operand A, and target is operand B.

Read it like this: "Take A, do something with it, and affect B."

What the fields mean

Every cell has two numeric fields: an A-field and a B-field. Modifiers decide whether the opcode uses A, B, or both.

DAT  3   5
    A   B

Example: with ADD.AB, the source A-field is added into the destination B-field.

Addressing modes

# Immediate

Use the number itself. Do not treat it as an address.

MOV  #5   10

This uses the literal value 5.

Bare value = Direct

A plain number or label points to a memory cell.

MOV  bomb   target

In this visualizer, bare numeric operands are relative to the current instruction.

* Relative

Explicit relative addressing from the current instruction.

JMP  *-3

Good when you want to make “relative” intent obvious.

@ Indirect

Go to a cell, read its B-field, then use that as an extra offset.

MOV  bomb   @ptr

Very common in pointers and scanners.

< Predecrement

First decrement the referenced cell’s B-field, then use it.

MOV  bomb   <ptr

Useful for stepping backward through memory.

> Postincrement

Use the referenced cell first, then increment its B-field.

MOV  bomb   >ptr

Useful for stepping forward through memory.

Beginner trap: # means “this is a value,” while bare operands, *, @, <, and > all lead to memory addresses in different ways.

Modifiers

Modifiers decide which fields an instruction touches. This is where a lot of Core War power comes from.

.A
A to A

Use source A-field and destination A-field.

ADD.A  src   dst
.B
B to B

Use source B-field and destination B-field.

ADD.B  src   dst
.AB
A to B

Take source A-field and apply it to destination B-field.

ADD.AB src   dst
.BA
B to A

Take source B-field and apply it to destination A-field.

ADD.BA src   dst
.F
Pairwise

Work on both fields pairwise: A→A and B→B.

ADD.F  src   dst
.X
Cross

Cross the fields: A→B and B→A.

ADD.X  src   dst
.I
Whole instruction

Treat the full instruction as the thing being compared or copied.

MOV.I  src   dst
Default modifiers used by the visualizer:
MOV → .I
ADD SUB MUL DIV MOD → .F
SEQ SNE → .I
SLT JMZ JMN DJN → .B

Main opcodes

DAT
Process killer

If a process executes DAT, that process dies immediately.

DAT  0   0

Mostly used as bombs or as data storage, not as a live instruction.

Important: DAT is not the only thing that kills a process. In your visualizer, any invalid instruction execution is also death. If a process steps onto garbage, malformed code, or even a plain 0 that does not decode into a valid instruction, that process dies too.

MOV
Copy

Copy from operand A to operand B.

MOV.I  source   target

This is the heart of replicators, bombers, and many scanners.

ADD
Add

Add values from A into B.

ADD.F  step   ptr

Often used to move a pointer through memory.

SUB
Subtract

Subtract values from A out of B.

SUB.F  step   ptr

Useful for walking backward or counting down.

MUL
Multiply

Multiply B by A.

MUL.B  factor   target

Less common, but can build unusual stepping patterns.

DIV
Divide

Divide B by A using integer division.

DIV.B  divisor   target

Division by zero kills the process with an error.

MOD
Remainder

Replace B with the remainder from B divided by A.

MOD.B  divisor   target

Modulo by zero is also fatal.

JMP
Unconditional jump

Always jump to operand A.

JMP  loop

The simplest loop instruction.

JMZ
Jump if zero

If the tested part of B is zero, jump to A. Otherwise continue normally.

JMZ.B  target   check

Good for branching on counters or empty-looking data.

JMN
Jump if non-zero

If the tested part of B is not zero, jump to A.

JMN.B  loop   counter

Think of this as the opposite of JMZ.

JMG
Jump if greater than zero

If the tested part of B is greater than zero, jump to A.

JMG.B  alive   value

This is a custom instruction in your visualizer, useful for positive-only tests.

DJN
Decrement and jump if non-zero

First decrement B, then test it. If it is still not zero, jump to A.

DJN.B  loop   counter

One of the best loop-building instructions in Core War.

DJZ
Decrement and jump if zero

First decrement B, then jump only if the result is exactly zero.

DJZ.B  done   counter

Custom to your visualizer. Great for “jump when the countdown reaches zero.”

SEQ
Skip if equal

If A and B are equal, skip the next instruction.

SEQ.I  probe   target

Usually used in scanners. Equal means the next line is skipped.

SNE
Skip if not equal

If A and B are different, skip the next instruction.

SNE.I  probe   target

Useful when you want to react to “something changed here.”

SLT
Skip if less than

If A is less than B, skip the next instruction.

SLT.B  a   b

A comparison tool rather than a movement tool.

CMG
Continue if A is greater

If A is greater than B, execution continues normally. Otherwise it skips the next instruction.

CMG.B  a   b

Custom to your visualizer. It behaves like a “greater than” test with skip logic.

RAN
Random write

Generate a random number and write it into operand B.

RAN  #-40   target

In your visualizer, the range is 0..max(0, (CORE-1)+A). So operand A changes the maximum range.

SWI
Swap two cells

Swap the entire instruction at A with the entire instruction at B.

SWI  ref1   ref2

This swaps whole cells, not just a single number.

SLP
Sleep

Pause the current process for A cycles, then resume later.

SLP  #5

Useful for timing tricks or slowing part of a warrior down.

NOP
Do nothing

Do nothing and move to the next instruction.

NOP

Helpful as a placeholder while testing.

SPL
Spawn process

Create a new process at operand A, while the current process keeps going.

SPL  child

This is how papers and process-heavy warriors multiply their activity.

Assembler directives

Directive What it does Simple example
ORG Sets the starting execution point of the program. ORG start
EQU Defines a constant or reusable expression. STEP EQU 5
Labels Name a location so you can jump to it or reference it later. loop: MOV bomb, @ptr
Your visualizer supports expressions with labels and EQU, so something like boot+41 can resolve as a numeric expression.

Three beginner patterns

1) Endless loop

loop    JMP   loop

2) Simple copier

start   MOV.I source   target
        JMP   start
source  DAT   0   0
target  DAT   0   0

3) Countdown loop

loop    MOV.I bomb   @ptr
        DJN.B loop   count
ptr     DAT   0   0
count   DAT   0   5
bomb    DAT   0   0

Most common beginner mistakes

Using # when you meant an address. Immediate values are not memory locations.

Forgetting what gets written. Most opcodes change operand B, not operand A.

Using the wrong modifier. .AB and .F are very different.

Jumping into a DAT. That kills the process instantly.

Assuming only DAT kills. In your visualizer, any non-valid instruction is fatal when executed. That means corrupted code, malformed instructions, and simple bombs like 0 can all work as killers.

Spawning too much with SPL. A process explosion can help, but it can also make your own warrior chaotic.

Quick opcode cheat sheet

Opcode Plain-English meaning Typical use
DATProcess dies if it lands hereBombs, data
MOVCopy A into BReplication, bombing
ADDAdd A into BPointer stepping
SUBSubtract A from BReverse stepping
MULMultiply B by APattern tricks
DIVDivide B by AMath / niche tricks
MODRemainder of B by ARange / cycle tricks
JMPAlways jumpLoops
JMZJump if B is zeroBranching
JMNJump if B is not zeroBranching
JMGJump if B is greater than zeroPositive-only test
DJNDecrement B, jump if non-zeroCountdown loops
DJZDecrement B, jump if zero“Jump on final tick” loops
SEQSkip next if equalScanners
SNESkip next if not equalScanners
SLTSkip next if A < BComparisons
CMGDo not skip only when A > BCustom compare-flow control
RANWrite a random value into BChaos, experiments
SWISwap two whole cellsWeird control tricks
SLPSleep for A cyclesTiming
NOPDo nothingPadding
SPLSpawn a new processMulti-process warriors
What is Core War?