# Moving values around

[Courses](https://asm-editor.specy.app/learn/courses.md) › [MIPS assembly](https://asm-editor.specy.app/learn/courses/mips.md) › Examples

Web page: https://asm-editor.specy.app/learn/courses/mips/examples/moving-values

> Place values in registers, preserve the inputs while computing a perimeter, copy a result, and observe subtraction order.

The same program in: [M68K](https://asm-editor.specy.app/learn/courses/m68k/examples/moving-values.md), [RISC-V](https://asm-editor.specy.app/learn/courses/risc-v/examples/moving-values.md), [Z80](https://asm-editor.specy.app/learn/courses/z80/examples/moving-values.md), [x86-64](https://asm-editor.specy.app/learn/courses/x86/examples/moving-values.md)

This program places a rectangle's width and height in `$t0` and `$t1`, then calculates its
perimeter in another register. Select **Build**, then use **Step** to watch the registers change one
instruction at a time.

```mips
.text
main:
    li   $t0, 30          # width
    li   $t1, 12          # height
    add  $t2, $t0, $t1   # width + height
    add  $t2, $t2, $t2   # perimeter = 2 * (width + height)

    move $t3, $t2         # copy the perimeter
    add  $t4, $t2, $zero  # copy it again with addition
    sub  $t5, $t0, $t1   # width - height

    li   $v0, 10          # exit
    syscall
```

Arithmetic instructions use the destination-first shape
`instruction destination, source, source`. The first `add` reads `$t0` and `$t1` but writes only
`$t2`, so the original width and height remain available. The second `add` doubles their sum.

`move $t3, $t2` copies `$t2` into `$t3`. `add $t4, $t2, $zero` also copies the value, because
`$zero` always reads as 0. Both leave `$t2` alone. `move` is a pseudo-instruction: the assembler
translates it into an instruction the processor can execute. Here you can read it simply as a copy.

Subtraction makes source order visible. `sub $t5, $t0, $t1` means `$t5 = $t0 - $t1`, so swapping
the last two operands would produce `12 - 30 = -18` instead.

Once the program stops after the exit syscall, the registers panel shows hexadecimal values by
default. The decimal column gives the corresponding numbers used in the calculation:

| Register | Meaning             | Shown in panel | Decimal |
| -------- | ------------------- | -------------- | ------: |
| `$t0`    | width, preserved    | `0000001E`     |      30 |
| `$t1`    | height, preserved   | `0000000C`     |      12 |
| `$t2`    | perimeter           | `00000054`     |      84 |
| `$t3`    | copied perimeter    | `00000054`     |      84 |
| `$t4`    | copied perimeter    | `00000054`     |      84 |
| `$t5`    | width minus height  | `00000012`     |      18 |
| `$v0`    | exit service number | `0000000A`     |      10 |

Now compute the same two results for inputs supplied by the test: leave twice the sum of `$t0` and
`$t1` in `$t2`, and `$t0 - $t1` in `$t3`. Keep `$t0` and `$t1` unchanged. For `$t0 = 7` and
`$t1 = 4`, what values will the three arithmetic instructions leave in `$t2` and `$t3`? Write them
in the exercise editor, then select **Test** to check the final values of `$t0`, `$t1`, `$t2`, and
`$t3`.

After your program passes, you can try another pair. Select **Open in editor** on the exercise,
then **Testcases**, then **+ New testcase**. Add a row with **+ Add register** for each of `$t0`,
`$t1`, `$t2`, `$t3` and `$v0`, picking the register in the row's first column. Type the new `$t0`
and `$t1` values under **Start** and the values you expect under **Expected**, in decimal or in hex
such as `0x16` (10 for `$v0`, the exit service). Then select **Run all**.

*Exercise: the code to start from, checked by the testcase after it:*

```mips
.text
main:
    # $t0 and $t1 are supplied by the test.
    # Compute the perimeter in $t2 and $t0 - $t1 in $t3.

    li   $v0, 10
    syscall
```

*Testcase for the program above (JSON):*

```json
{
    "startingRegisters": { "$t0": 7, "$t1": 4 },
    "expectedRegisters": { "$t0": 7, "$t1": 4, "$t2": 22, "$t3": 3, "$v0": 10 }
}
```

<details>
<summary>Show solution</summary>

*Solution:*

```mips
.text
main:
    add  $t2, $t0, $t1
    add  $t2, $t2, $t2
    sub  $t3, $t0, $t1

    li   $v0, 10
    syscall
```

</details>

## Instructions in this Lecture

- MIPS: [`li`](https://asm-editor.specy.app/documentation/mips/instruction/li.md), [`add`](https://asm-editor.specy.app/documentation/mips/instruction/add.md), [`move`](https://asm-editor.specy.app/documentation/mips/instruction/move.md), [`sub`](https://asm-editor.specy.app/documentation/mips/instruction/sub.md), [`syscall`](https://asm-editor.specy.app/documentation/mips/instruction/syscall.md)

Previous: [Exceptions and coprocessor 0](https://asm-editor.specy.app/learn/courses/mips/talking-to-the-outside-world/exceptions-and-coprocessor-0.md)

Next: [Variables in memory and constants](https://asm-editor.specy.app/learn/courses/mips/examples/variables-in-memory.md)
