### **NOP**

`NOP` - No operation (does nothing, advances to the next instruction)

### **BRK**

`BRK` - Pause CPU (halts execution until resumed)

### **HLT**

`HLT` - Halt CPU execution

### **MOV_IMM_RN**

`MOV R1, 0x10` - Move immediate value `0x10` to register `R1`

### **MOV_RN_RM**

`MOV R2, R1` - Move value from `R1` to `R2`

### **MOV_RN_ADDR**

`MOV R3, [0x2000]` - Load value from memory address `0x2000` into `R3`

### **MOV_ADDR_RN**

`MOV [0x2000], R1` - Store `R1` value to memory address `0x2000`

### **SWAP**

`SWAP R1, R2` - Swap values between `R1` and `R2`

### **SWAPN**

`SWAPN R1` - Swap nibbles within `R1`

### **ADD_RN_RM**

`ADD R1, R2` - Add `R2` to `R1` (`R1 = R1 + R2`)

### **ADD_RN_IMM**

`ADD R1, 0x10` - Add immediate `0x10` to `R1` (`R1 = R1 + 0x10`)

### **SUB_RN_RM**

`SUB R1, R2` - Subtract `R2` from `R1` (`R1 = R1 - R2`)

### **SUB_RN_IMM**

`SUB R1, 0x10` - Subtract immediate `0x10` from `R1` (`R1 = R1 - 0x10`)

### **MUL_RN_RM**

`MUL R1, R2` - Multiply `R1` by `R2` (`R1 = R1 * R2`)

### **MUL_RN_IMM**

`MUL R1, 0x10` - Multiply `R1` by immediate `0x10` (`R1 = R1 * 0x10`)

### **DIV_RN_RM**

`DIV R1, R2` - Divide `R1` by `R2` (`R1 = R1 / R2`)

### **DIV_RN_IMM**

`DIV R1, 0x10` - Divide `R1` by immediate `0x10` (`R1 = R1 / 0x10`)

### **MOD_RN_RM**

`MOD R1, R2` - Compute remainder of `R1 / R2` (`R1 = R1 % R2`)

### **MOD_RN_IMM**

`MOD R1, 0x10` - Compute remainder of `R1 / 0x10` (`R1 = R1 % 0x10`)

### **NEG_RN**

`NEG R1` - Negate `R1` (`R1 = -R1`)

### **AND_RN_RM**

`AND R1, R2` - Bitwise AND of `R1` and `R2` (`R1 = R1 & R2`)

### **AND_RN_IMM**

`AND R1, 0x10` - Bitwise AND `R1` with immediate `0x10` (`R1 = R1 & 0x10`)

### **OR_RN_RM**

`OR R1, R2` - Bitwise OR of `R1` and `R2` (`R1 = R1 | R2`)

### **OR_RN_IMM**

`OR R1, 0x10` - Bitwise OR `R1` with immediate `0x10` (`R1 = R1 | 0x10`)

### **XOR_RN_RM**

`XOR R1, R2` - Bitwise XOR of `R1` and `R2` (`R1 = R1 ^ R2`)

### **XOR_RN_IMM**

`XOR R1, 0x10` - Bitwise XOR `R1` with immediate `0x10` (`R1 = R1 ^ 0x10`)

### **NOT_RN**

`NOT R1` - Bitwise NOT of `R1` (`R1 = ~R1`)

### **SHL_RN_IMM**

`SHL R1, 2` - Logical shift left `R1` by `2` bits

### **SHR_RN_IMM**

`SHR R1, 2` - Logical shift right `R1` by `2` bits

### **SAR_RN_IMM**

`SAR R1, 2` - Arithmetic shift right `R1` by `2` bits (sign extended)

### **JMP**

`JMP 0x3000` - Jump to address `0x3000`

### **JMP_REL**

`JMP +5` - Jump `5` bytes forward

### **INC_RN**

`INC R1` - Increment `R1`

### **INC_ADDR**

`INC [0x2000]` - Increment value at memory address `0x2000`

### **DEC_RN**

`DEC R1` - Decrement `R1`

### **DEC_ADDR**

`DEC [0x2000]` - Decrement value at memory address `0x2000`

### **CMP**

`CMP R1, R2` - Compare `R1` and `R2` (sets flags based on `R1 - R2`)

### **JE**

`JE 0x4000` - Jump to `0x4000` if equal (zero flag set)

### **JNE**

`JNE 0x4000` - Jump to `0x4000` if not equal (zero flag not set)

### **JG**

`JG 0x4000` - Jump to `0x4000` if greater

### **JL**

`JL 0x4000` - Jump to `0x4000` if less

### **JGE**

`JGE 0x4000` - Jump to `0x4000` if greater or equal

### **JLE**

`JLE 0x4000` - Jump to `0x4000` if less or equal

### **CALL**

`CALL 0x5000` - Call subroutine at `0x5000`

### **RET**

`RET` - Return from subroutine

### **BIT_TC_RN**

`JMPBC R1, 3, 0x4000` - Jump to address `0x4000` if bit `3` in register `R1` is **not set**.

### **BIT_TC_ADDR**

`JMPBC 0x2000, 5, 0x5000` - Jump to address `0x5000` if bit `5` in memory at address `0x2000` is **not set**.

### **BIT_TS_RN**

`JMPBS R2, 1, 0x6000` - Jump to address `0x6000` if bit `1` in register `R2` **is set**.

### **BIT_TS_ADDR**

`JMPBS 0x3000, 7, 0x7000` - Jump to address `0x7000` if bit `7` in memory at address `0x3000` **is set**.

### **BITS_ADDR**

`BITS [0x2000], 3` - Set bit `3` in memory at address `0x2000`

- Reads a memory address as an argument.
- Reads a bit index from the next byte.
- Ensures the bit index is between `0-7`.
- Sets the specified bit in the memory address.
- Increments the program counter.

### **BITC_ADDR**

`BITC [0x2000], 5` - Clear bit `5` in memory at address `0x2000`

- Reads a memory address as an argument.
- Reads a bit index from the next byte.
- Ensures the bit index is between `0-7`.
- Clears the specified bit in the memory address.
- Increments the program counter.

### **BITS_RN**

`BITS R1, 2` - Set bit `2` in register `R1`

- Reads a register number.
- Reads a bit index from the next byte.
- Ensures the register is valid (`0 - REG_COUNT - 1`).
- Ensures the bit index is between `0-7`.
- Sets the specified bit in the register.
- Increments the program counter.

### **BITC_RN**

`BITC R2, 6` - Clear bit `6` in register `R2`

- Reads a register number.
- Reads a bit index from the next byte.
- Ensures the register is valid (`0 - REG_COUNT - 1`).
- Ensures the bit index is between `0-7`.
- Clears the specified bit in the register.
- Increments the program counter.

### **BITS (Special Instruction)**

- This mnemonic decides between `BITS_RN` and `BITS_ADDR` based on the operand.
- If the operand is a register, `BITS_RN` is used.
- If the operand is a memory address, `BITS_ADDR` is used.

### **BITC (Special Instruction)**

- This mnemonic decides between `BITC_RN` and `BITC_ADDR` based on the operand.
- If the operand is a register, `BITC_RN` is used.
- If the operand is a memory address, `BITC_ADDR` is used.

