# A jump table

[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/jump-table

> Use an in-range index to load a code address from a table and jump to the selected operation.

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

A **jump table** lets a number choose where a program continues. Here `$t2` holds an operation
number, and the table holds the addresses of four pieces of code. With `$t2 = 2`, the program
jumps to `mul_op` and leaves `18` in `$t6`.

| `$t2` | Table entry | Result for 6 and 3 |
| ----: | ----------- | -----------------: |
|     0 | `add_op`    |                  9 |
|     1 | `sub_op`    |                  3 |
|     2 | `mul_op`    |                 18 |
|     3 | `div_op`    |                  2 |

This version assumes `$t2` is between 0 and 3. If an operation number can come from outside the
program, check that it is in range before using it as a table index. An out-of-range load could
give `jr` an address that does not point to the intended code.

```mips
.data
table: .word add_op, sub_op, mul_op, div_op

.text
main:
    li $t0, 6               # a = 6
    li $t1, 3               # b = 3
    li $t2, 2               # operation number

    la $t3, table           # address of the first table entry
    sll $t4, $t2, 2         # index * 4 bytes per word
    add $t4, $t3, $t4       # address of the chosen entry
    lw $t5, 0($t4)          # load the code address stored there
    jr $t5                  # jump to that address

add_op:
    add $t6, $t0, $t1
    j done
sub_op:
    sub $t6, $t0, $t1
    j done
mul_op:
    mul $t6, $t0, $t1
    j done
div_op:
    div $t6, $t0, $t1

done:
    li $v0, 10              # end the program
    syscall
```

`.word` stores one four-byte address for each code label in the table, even though the table is in
the data area and the labelled instructions are in the code area. The assembler turns each label
name into its code address. You do not need to know those numeric addresses to use them.

Follow the chosen index: `2` becomes the byte offset `8` when `sll` multiplies it by four.
Adding that offset to `table` reaches its third word, which contains the address of `mul_op`.
`lw` puts that address in `$t5`, and `jr $t5` jumps there. This is the same base-plus-offset
lookup used for an array of numbers; the loaded word happens to be an address. `jr` jumps to the
address in its register. The familiar `jr $ra` uses that same instruction to return from a
subroutine.

After `mul_op` calculates `6 * 3`, `j done` skips the other operations. The add and subtract
paths jump to `done` for the same reason. `div_op` is last, so it reaches `done` by continuing to
the next instruction. The exit syscall stops the program with the answer still in `$t6`.

Select **Build** and **Run**, then look at `$t6` in the register panel. It should show `18`
(`00000012` in hexadecimal). Change `li $t2, 2` to each other valid index—0, 1, and 3—and
predict `$t6` before selecting **Build**, then **Run** each time. Which table word does each index
load? The lookup follows the same steps for every valid index; only the loaded address and the
chosen operation change.

## Instructions in this Lecture

- MIPS: [`li`](https://asm-editor.specy.app/documentation/mips/instruction/li.md), [`la`](https://asm-editor.specy.app/documentation/mips/instruction/la.md), [`sll`](https://asm-editor.specy.app/documentation/mips/instruction/sll.md), [`add`](https://asm-editor.specy.app/documentation/mips/instruction/add.md), [`lw`](https://asm-editor.specy.app/documentation/mips/instruction/lw.md), [`jr`](https://asm-editor.specy.app/documentation/mips/instruction/jr.md), [`j`](https://asm-editor.specy.app/documentation/mips/instruction/j.md), [`sub`](https://asm-editor.specy.app/documentation/mips/instruction/sub.md), [`mul`](https://asm-editor.specy.app/documentation/mips/instruction/mul.md), [`div`](https://asm-editor.specy.app/documentation/mips/instruction/div.md), [`syscall`](https://asm-editor.specy.app/documentation/mips/instruction/syscall.md)

Previous: [Bubble sort](https://asm-editor.specy.app/learn/courses/mips/examples/bubble-sort.md)

Next: [Binary search](https://asm-editor.specy.app/learn/courses/mips/examples/binary-search.md)
