# The 32 registers and their names

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

Web page: https://asm-editor.specy.app/learn/courses/mips/introduction/the-32-registers

> Learn the numbered and named forms of MIPS registers, use $zero in simple calculations, and choose safe registers for beginner programs.

Overview of this topic: [Assembly basics](https://asm-editor.specy.app/learn/courses/assembly-basics/introduction/registers.md)

The same topic in: [M68K](https://asm-editor.specy.app/learn/courses/m68k/introduction/data-and-address-registers.md), [RISC-V](https://asm-editor.specy.app/learn/courses/risc-v/introduction/the-32-registers.md), [Z80](https://asm-editor.specy.app/learn/courses/z80/introduction/registers-pairs-and-the-shadow-set.md), [x86-64](https://asm-editor.specy.app/learn/courses/x86/introduction/the-16-registers-and-their-halves.md)

MIPS has 32 registers, and each one holds 32 bits. The hardware identifies them by number, from
`$0` to `$31`. Programmers normally use names such as `$t0`, `$s0`, and `$sp` because the names are
easier to recognize.

A number and its usual name refer to the same storage location. For example, `$t0` and `$8` are two
names for register 8. Changing one changes the other.

The `add` and `sub` instructions put their result in the first register:

```text
add destination, left, right      # destination = left + right
sub destination, left, right      # destination = left - right
```

```mips
.text
main:
    li $t0, 5
    add $8, $8, $8      # $8 is $t0, so this doubles 5
    li $9, 7            # $9 is $t1
    add $t2, $t1, $t1   # this doubles the 7 stored above
```

Build the program and step through it. After the second instruction, `$t0` contains 10 even though
that line uses the name `$8`. After the last instruction, `$t2` contains 14 because `$9` and `$t1`
refer to the same register.

You will usually write the named forms. The numbered forms are useful when a register panel,
documentation, or another program uses a different spelling.

## The register names

Here is the complete set of 32 registers. Use this table as a lookup; you do **not** need to memorize
it.

| number      | usual name  | practical meaning                                           |
| ----------- | ----------- | ----------------------------------------------------------- |
| `$0`        | `$zero`     | always reads as 0                                           |
| `$1`        | `$at`       | reserved for the assembler; leave it alone                  |
| `$2`–`$3`   | `$v0`–`$v1` | values returned by subroutines                              |
| `$4`–`$7`   | `$a0`–`$a3` | arguments passed to subroutines                             |
| `$8`–`$15`  | `$t0`–`$t7` | temporary values                                            |
| `$16`–`$23` | `$s0`–`$s7` | saved values                                                |
| `$24`–`$25` | `$t8`–`$t9` | two more temporary values                                   |
| `$26`–`$27` | `$k0`–`$k1` | reserved for the operating system; leave them alone         |
| `$28`       | `$gp`       | global pointer; used by a program-wide convention           |
| `$29`       | `$sp`       | stack pointer; introduced when the course reaches the stack |
| `$30`       | `$s8`/`$fp` | saved register or frame pointer, depending on the program   |
| `$31`       | `$ra`       | return address for a subroutine                             |

For the small, self-contained programs in this part of the course, use `$t0` through `$t9` for
values you choose yourself. They are the simplest safe default. In programs that do not call
subroutines yet, `$s0` through `$s7` can also hold your values; some exercises use them so their
names become familiar. The difference between **temporary** and **saved** matters when one part of
a program calls another, so the course will make that distinction concrete when it introduces
subroutines.

The other names are job labels used by common MIPS programming rules. They will become useful when
the corresponding jobs appear. For now, the practical cautions are enough: do not keep your own
values in `$at`, `$k0`, or `$k1`, and do not change `$sp` until you learn how the stack uses it.

## `$zero` always contains zero

Register `$0`, usually written `$zero`, is the one member of the 32 that the hardware treats
differently. Reading it always gives 0. An instruction may try to write to it, but the attempted
write is discarded.

That makes `$zero` useful in ordinary calculations. Step through this program:

```mips
.text
main:
    li $t0, 5
    add $t1, $t0, $zero     # 5 + 0: copy $t0 into $t1
    sub $t2, $zero, $t0     # 0 - 5: put -5 in $t2
    li $t3, 9
    add $zero, $t3, $t3     # try to write 18 to $zero
    add $t4, $zero, $zero   # $zero still reads as 0
```

After stepping through it, `$t1` contains 5 and `$t2` contains -5. The attempted write to `$zero`
does not remain anywhere, so `$t4` receives 0 on the final line.

## A few names outside the 32

The registers panel also shows `hi`, `lo`, and `pc`. They are not extra general-purpose registers.
`pc` identifies the next instruction to run, while `hi` and `lo` are used by later arithmetic
instructions. You can leave all three alone for now.

## Your turn

The test starts `$t0` at 5. Leave a copy of it in `$s0` and its negation in `$s1`. Use `$zero` in
both instructions rather than a shorthand instruction.

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

```mips
.text
main:
    # your code here
```

*Testcase for the program above (JSON):*

```json
{
    "startingRegisters": { "$t0": 5 },
    "expectedRegisters": { "$s0": 5, "$s1": -5 }
}
```

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

*Solution:*

```mips
.text
main:
    add $s0, $t0, $zero     # 5 + 0 copies the value
    sub $s1, $zero, $t0     # 0 - 5 negates the value
```

</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), [`sub`](https://asm-editor.specy.app/documentation/mips/instruction/sub.md)

Previous: [Getting started with MIPS](https://asm-editor.specy.app/learn/courses/mips/introduction/getting-started.md)

Next: [.data, .text and directives](https://asm-editor.specy.app/learn/courses/mips/introduction/data-text-and-directives.md)
