From 63ce71d5de161f4afdcddfcdc430a1993fefca90 Mon Sep 17 00:00:00 2001 From: gareth Date: Mon, 2 Jul 2018 13:38:55 +0100 Subject: [PATCH] Example of addressing mode gotcha --- docs/redcode/execution.md | 68 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/docs/redcode/execution.md b/docs/redcode/execution.md index 98d29c5e..2449d9c5 100644 --- a/docs/redcode/execution.md +++ b/docs/redcode/execution.md @@ -14,7 +14,7 @@ The following notional registers are used: |Source Register|The source instruction| |Destination Register|The destination instruction| -**Copies** of instructions are written to these registers. Therefore changes made to the original instructions in the [Core](core) after they are copied to a register, do not affect the data in the registers themselves. +**Copies** of instructions are written to these registers. Therefore changes made to the original instructions in the [Core](core) after they are copied to a register, do not affect the data in the registers themselves. This can be best explained with a few [examples](#examples). #Fetch @@ -53,3 +53,69 @@ The operation is performed using the instructions in the `Source Register` and ` Note that some opcodes (such as [jmp](opcodes#jmp-jump)) will modify the current process's `instruction pointer`, overwritting the current value. Finally, the current warrior's active process is moved to the next process in the warrior's process list and the game's active warrior is moved to the next warrior in the game's list of active warriors. + +## Examples + +Understanding how instructions are evaluated and executed is vitally important to writing correctly functioning warriors, unfortunately it is also something which can be very difficult for beginners to understand. Here are a few examples to aid understanding. + +### The executing instruction is modified during evaluation of addressing modes + +Consider the following redcode: + +``` +0000: mov.i >0, $0 +0001: dat.f $0, $0 +``` + +The instructions have been prefixed with a number indicating their absolute address in the [Core](core). + +When imaging how this first instruction will execute, your reasoning might be: + +*The [B Post-Increment Indirect](addressing_modes#b-post-increment-indirect) (`>`) addressing mode will increase the `B` number of the instruction from 0 to 1 and then the instruction at address 0 will be copied to address 1.* + +Naively, you might therefore expect the core to look like this after the first instruction is executed: + +``` +0000: mov.i >0, $1 +0001: mov.i >0, $1 +``` + +However, this is **incorrect**. + +During the [fetch](#fetch) stage, the instruction `mov.i >0, $0` will be copied to the `Instruction Register`. + +|Instruction Register|Source Register|Destination Register| +|---|---|---| +|`0000: mov.i >0, $0`| | | + +Next, during the [decode](#decode) stage, the `A` operand will be evaluated. The addressing mode (`>`) means that the instruction pointed to by the B number will be used as the address of the `source instruction`. Therefore, the current instruction is copied to the `Source Register`. + +|Instruction Register|Source Register|Destination Register| +|---|---|---| +|`0000: mov.i >0, $0`|`0001: mov.i >0, $0`| | + +Following this the post-increment is applied to the `B` operand so the instruction in core looks like this: + +``` +0000: mov.i >0, $1 +0001: dat.f $0, $0 +``` + +However, the instruction in the `Source Register` is still `mov.i >0, $0`. + +Next the `B` operand will be evaluated using the direct (`$`) addressing mode. The `B` number is `1`, which references the following instruction (`dat.f $0, $0`). Therefore the `dat` instruction is copied to the `Destination Register`. + +|Instruction Register|Source Register|Destination Register| +|---|---|---| +|`0000: mov.i >0, $0`|`0000: mov.i >0, $0`|`0001: dat.f $0, $0`| + +Now the instruction in the `Instruction Register` is executed. It copies the instruction in the `Source Register` to the address stored in the `Destination Register`. + +The resulting core looks like this: + +``` +0000: mov.i >0, $1 +0001: mov.i >0, $0 +``` + +So in fact, this instruction will continue to execute safetly, in a similar fashion to the classic `imp`.