mirror of
				https://github.com/simon987/Much-Assembly-Required.git
				synced 2025-11-04 10:06:54 +00:00 
			
		
		
		
	Added first draft of instructions up to 0x1D
				
			
							parent
							
								
									53571e7e73
								
							
						
					
					
						commit
						804af72104
					
				@ -63,3 +63,534 @@ Operand value:
 | 
				
			|||||||
| Register | `00001`-`01000` |
 | 
					| Register | `00001`-`01000` |
 | 
				
			||||||
| [Register]  | `01001`-`10000` |
 | 
					| [Register]  | `01001`-`10000` |
 | 
				
			||||||
| Register + Immediate value at IP+1 | `10001`-`11000` |
 | 
					| Register + Immediate value at IP+1 | `10001`-`11000` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					***
 | 
				
			||||||
 | 
					> NOTE: Work In Progress
 | 
				
			||||||
 | 
					# Instruction Set
 | 
				
			||||||
 | 
					## Introduction
 | 
				
			||||||
 | 
					This is an effort to specify the specific MAR Assembly Instruction Set and its behaviour. The instruction set is a subset of the 8086 instruction set. A more detailed specification if the 8086 Instruction Set can be found [here](http://www.ousob.com/ng/iapx86/ng2e5.php). Note that the MAR Instruction Set can differ from the 8086 Instruction Set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This manual tries to describe how to use the instructions and show any side effects they might have.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each instruction has a `Mnemonic` or syntax. This is the way the instruction is written in human readable format. This exists of the instruction name and its operands (if any).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```s
 | 
				
			||||||
 | 
					MOV A, 0x20
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This human readable format is parsed by the assembler which will output the actual binary opcodes and operands. More about the encoding can be read [below](#Encoding).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Instructions
 | 
				
			||||||
 | 
					### BRK
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `BRK`    | `0x00` |          |  `-`  |  `-` |  `-` |    `-`   |  `1`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`BRK` sets the break flag. This will halt execution until the next game 'tick', where it will be cleared and execution resumes from the start of the `.text` label.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### MOV
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `MOV destination, source`    | `0x01` |  `destination` : `reg` / `mem` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`MOV` transfers (copies) a word from the source operand to the destination operand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = source
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### ADD
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `ADD destination, source`    | `0x02` |  `destination` : `reg` / `mem` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`ADD` replaces the destination operand with the sum of the source and destination operands. It sets the carry flag if there is an overflow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = destination + source
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### SUB
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `SUB destination, source`    | `0x03` |  `destination` : `reg` / `mem` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`SUB` subtracts the source operand from the destination operand and stores the result in destination.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> ? TODO: is this implemented?
 | 
				
			||||||
 | 
					> When an immediate byte value is subtracted from a word operand, the immediate value is first sign-extended to the size of the destination operand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = destination - source
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### AND
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `AND destination, source`    | `0x04` |  `destination` : `reg` / `mem` |  `0`  |  `X` |  `X` |    `0`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`AND` performs a bit-by-bit logical AND operation on its operands
 | 
				
			||||||
 | 
					    and stores the result in destination. `AND` sets each bit of the
 | 
				
			||||||
 | 
					    result to one if both of the corresponding bits of the operands
 | 
				
			||||||
 | 
					    are one.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = destination & source
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### OR
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `OR destination, source`    | `0x05` |  `destination` : `reg` / `mem` |  `0`  |  `X` |  `X` |    `0`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`OR` performs a bit-by-bit logical inclusive OR operation on its
 | 
				
			||||||
 | 
					    operands and returns the result to destination. `OR` sets each bit
 | 
				
			||||||
 | 
					    of the result to one if either or both of the corresponding bits
 | 
				
			||||||
 | 
					    of the operands are one.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = destination | source
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### SHL (Shift Logical Left)
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `SHL destination, count`    | `0x06` |  `destination` : `reg` / `mem` |  `X`  |  `-` |  `-` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `count` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`SHL` shifts the bits of the destination operand upward (toward the
 | 
				
			||||||
 | 
					    most significant bit) by the number of bit positions specified in
 | 
				
			||||||
 | 
					    the second operand (count). As bits are transferred out of the
 | 
				
			||||||
 | 
					    left (high-order) end of the destination, zero bits are shifted
 | 
				
			||||||
 | 
					    into the right (low-order) end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> ? TODO: is this implemented?
 | 
				
			||||||
 | 
					>   The carry flag (CF) is set equal
 | 
				
			||||||
 | 
					    to the last bit shifted out of the left end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = destination << count
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### SHR (Shift Logical Right)
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `SHR destination, count`    | `0x07` |  `destination` : `reg` / `mem` |  `X`  |  `-` |  `-` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `count` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					SHR shifts the bits of the destination operand downward (toward
 | 
				
			||||||
 | 
					    the least significant bit) by the number of bit positions
 | 
				
			||||||
 | 
					    specified in the second operand (count). As bits are transferred
 | 
				
			||||||
 | 
					    out of the right (low-order) end of the destination, zero bits are
 | 
				
			||||||
 | 
					    shifted into the left (high-order) end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> ? TODO: is this implemented?
 | 
				
			||||||
 | 
					>   The carry flag (CF) is set
 | 
				
			||||||
 | 
					    equal to the last bit shifted out of the right end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = destination >> count
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### HWI (Hardware Interrupt)
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `HWI source`    | `0x09` |  `source` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`HWI` triggers an [Hardware Interrupt](https://github.com/simon987/Much-Assembly-Required/wiki/Hardware). `source` should be the address of the harware device. This is differnt from the RAM memory addresses. See the documentation of the hardware devices to see what an `HWI` does for each device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JMP
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JMP target`    | `0x0A` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JMP` performs an unconditional jump to the target memory address and will resume execution there.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### TEST
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `TEST destination, source`    | `0x0B` |  `destination` : `reg` / `mem` |  `0`  |  `X` |  `X` |    `0`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`TEST` performs a logical AND operation on its two operands and
 | 
				
			||||||
 | 
					    updates the flags. None of the operands are changed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination & source      # flags will be set
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### CMP
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `CMP destination, source`    | `0x0C` |  `destination` : `reg` / `mem` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					| | | `source` : `reg` / `mem` / `imm` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`CMP` compares two numbers by subtracting the source from the
 | 
				
			||||||
 | 
					    destination and updates the flags. None of the operands are
 | 
				
			||||||
 | 
					    changed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination - source   # flags will be set
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JNZ
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JNZ target`    | `0x0D` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JNZ` performs a jump if the zero flag **IS NOT** set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if ZERO_FLAG == 0:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JZ
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JZ target`    | `0x0E` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JZ` performs a jump if the the zero flag **IS** set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if ZERO_FLAG == 1:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JG
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JG target`    | `0x0F` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JG` performs a jump if the sign flag **IS EQUAL** to the overflow flag **AND** the zero flag **IS NOT** set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if SIGN_FLAG == OVERFLOW_FLAG and ZERO_FLAG == 0:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JGE
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JGE target`    | `0x10` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JGE` performs a jump if the sign flag **IS EQUAL** to the overflow flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if SIGN_FLAG == OVERFLOW_FLAG:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JL
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JL target`    | `0x11` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JL` performs a jump if the sign flag **IS NOT EQUAL** to the overflow flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if SIGN_FLAG != OVERFLOW_FLAG:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JLE
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JLE target`    | `0x12` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JLE` performs a jump if the sign flag **IS NOT EQUAL** to the overflow flag **OR** the zero flag **IS** set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if SIGN_FLAG != OVERFLOW_FLAG or ZERO_FLAG == 1:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### PUSH
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `PUSH source`    | `0x13` |  `source` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`PUSH` decrements the stack pointer by one and then copies `source` to the address the stack pointer is pointing to.
 | 
				
			||||||
 | 
					> The stack grows downwards from 0xFFFF -> 0x0000
 | 
				
			||||||
 | 
					> So decrementing will 'grow' the stack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					SP = SP - 1
 | 
				
			||||||
 | 
					memory[SP] = source
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### POP
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `POP destintation`    | `0x14` |  `destination` : `reg` / `mem` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`POP` copies the value of the memory address specified in the stack pointer to the `destination` and increments the stack pointer.
 | 
				
			||||||
 | 
					> The stack grows downwards from 0xFFFF -> 0x0000
 | 
				
			||||||
 | 
					> So incrementing will 'shrink' the stack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					destination = memory[SP]
 | 
				
			||||||
 | 
					SP = SP + 1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### CALL
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `CALL target`    | `0x15` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`CALL` pushes the current instruction pointer on to the stack and then performs a jump to the `target` address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					SP = SP - 1
 | 
				
			||||||
 | 
					memory[SP] = IP
 | 
				
			||||||
 | 
					IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### RET
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `RET [amount]`    | `0x16` |  `amount` : `imm` / `None` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`RET` jumps to the address stored at the stack pointer and then increments (pops) that address of the stack.
 | 
				
			||||||
 | 
					When `amount` is given increment the stack pointer the number of times given in amount.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					IP = memory[SP]
 | 
				
			||||||
 | 
					if amount == None:
 | 
				
			||||||
 | 
					    amount = 0
 | 
				
			||||||
 | 
					SP = SP + 1 + amount
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### MUL
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `MUL source`    | `0x17` |  `source` : `mem` / `reg` / `imm` |  `X`  |  `-` |  `-` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`MUL` performs unsigned multiplication with `A` and `source` and stores the result into `Y:A`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The result of the multiplication is stored into `Y:A` where the higher order bits are stored in `Y` and the lower order bits are stored in `A`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The carry and overflow flags are set to 1 if the high-order of the result is bigger than 0; otherwise, CF and OF are reset to 0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> This is a somewhat complicated instruction
 | 
				
			||||||
 | 
					> See the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/MulInstruction.java) if needed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# result is a 32-bit integer
 | 
				
			||||||
 | 
					result = A * source
 | 
				
			||||||
 | 
					# get the 16 most significant bits of result
 | 
				
			||||||
 | 
					higher_order_word = (result & 0xff00)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if higher_order_word != 0:
 | 
				
			||||||
 | 
					    OVERFLOW_FLAG = 1
 | 
				
			||||||
 | 
					    CARRY_FLAG = 1
 | 
				
			||||||
 | 
					    Y = higher_order_word
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    OVERFLOW_FLAG = 0
 | 
				
			||||||
 | 
					    CARRY_FLAG = 0
 | 
				
			||||||
 | 
					A = (result & 0x00ff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# result is stored in Y:A
 | 
				
			||||||
 | 
					# you can check if you need Y by check the flags
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### DIV
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `DIV source`    | `0x18` |  `source` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `X`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`DIV` performs unsigned division on `A` with `source` as divisor and stores the result into `A` and the remainder in `Y`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that a division by 0 will set the (undocumented) error flag and the break flag. This will halt execution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> This is a somewhat complicated instruction
 | 
				
			||||||
 | 
					> See the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/DivInstruction.java) if needed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if source == 0:
 | 
				
			||||||
 | 
					    ERROR_FLAG = 1
 | 
				
			||||||
 | 
					    BREAK_FLAG = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# temp is a 32-bit integer
 | 
				
			||||||
 | 
					temp = (Y << 16) | A
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A = temp / source # result is floored
 | 
				
			||||||
 | 
					Y = temp % source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### NEG
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `NEG destintation`    | `0x19` |  `destination` : `mem` / `reg` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`NEG` subtracts the destination operand from 0 and returns the result in the destination. This effectively produces the two's complement of the operand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If the operand is zero, the carry flag is cleared; in all other cases, the carry flag is set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Attempting to negate a word containing -32,768 causes no change to the operand and sets the Overflow Flag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if destination == 0:
 | 
				
			||||||
 | 
					    CARRY_FLAG = 0
 | 
				
			||||||
 | 
					    ZERO_FLAG = 1
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    CARRY_FLAG = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if destination == -32768:
 | 
				
			||||||
 | 
					    OVERFLOW_FLAG = 1
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    destination = 0 - destination # or destination = destination + (-dest)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JS
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JS target`    | `0x1A` |  `target` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JS` jumps to the target if the sign flag **IS** set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if SIGN_FLAG == 1:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### JNS
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `JNS target`    | `0x1B` |  `target` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`JNS` jumps to the target if the sign flag **IS NOT** set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if SIGN_FLAG == 0:
 | 
				
			||||||
 | 
					    IP = target
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### HWQ
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `HWQ source`    | `0x1C` |  `source` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`HWQ` queries the hardware id of the hardware at the hardware address specified by `source`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					if hardware_memory[source] != None:
 | 
				
			||||||
 | 
					    B = get_hardware_id(hardware_memory[source]) # not sure how to (pseudo) code this
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    B = 0
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### NOT
 | 
				
			||||||
 | 
					#### Details
 | 
				
			||||||
 | 
					| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
				
			||||||
 | 
					| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
				
			||||||
 | 
					| `NOT destintation`    | `0x1D` |  `source` : `mem` / `reg` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Description
 | 
				
			||||||
 | 
					`NOT` inverts each bit in its operand, i.e. forms the one's complement.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pseudo code
 | 
				
			||||||
 | 
					```py
 | 
				
			||||||
 | 
					dest = ~dest
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user