# `movem`

[M68K Documentation](https://asm-editor.specy.app/documentation/m68k.md) › [Instructions](https://asm-editor.specy.app/documentation/m68k/instruction.md)

Web page: https://asm-editor.specy.app/documentation/m68k/instruction/movem

**Move multiple registers**

Category: Load and store

Moves a list of registers such as d0-d7 and a0-a7 to or from memory.

Sizes .w .l, .w by default

Used in: [The stack, -(sp) and movem](https://asm-editor.specy.app/learn/courses/m68k/think-in-assembly/the-stack-and-movem.md) (M68K assembly), [Interrupts and cycles](https://asm-editor.specy.app/learn/courses/m68k/talking-to-the-outside-world/interrupts-and-cycles.md) (M68K assembly)

## Flags

| Flag | Effect |
| --- | --- |
| X | not changed |
| N | not changed |
| Z | not changed |
| V | not changed |
| C | not changed |

## Forms

- `movem <register list>, <ea>`
  - Source: Dn, An, <register list>
  - Destination: (An), -(An), d(An), d(An,Xn), abs
- `movem <ea>, <register list>`
  - Source: (An), (An)+, d(An), d(An,Xn), abs, d(PC), d(PC,Xn)
  - Destination: Dn, An, <register list>

## Operands

- `<register list>`: A register list using `/` to separate registers and `-` for ranges. For example, `d0-d2/a0` selects `d0`, `d1`, `d2` and `a0`. A single data or address register is also valid.
- [`<ea>`](https://asm-editor.specy.app/documentation/m68k/addressing-mode.md): An operand using one of the addressing modes listed for this form. The list determines whether it can be a register, memory or an immediate value. With `opt p=68020`, an allowed `d(An,Xn)` or `d(PC,Xn)` mode also permits the corresponding 68020 indexed and memory indirect forms. See [68020 addressing](https://asm-editor.specy.app/documentation/m68k/addressing-mode/68020.md).

## Description

Put the register list first to store the registers and second to load them. This is useful for saving registers before a subroutine uses them and restoring them afterward.

Use `/` between registers and `-` for a range. For example, `a3-a5/d0-d2` selects `d0`, `d1`, `d2`, `a3`, `a4` and `a5`. The written order does not control the transfer order: selected data registers are processed from `d0` to `d7`, then selected address registers from `a0` to `a7`. A predecrement store processes them in reverse order, from `a7` to `a0`, then `d7` to `d0`.

## Example

```m68k
move.l #$1, d0
move.l #$2, d1
move.l #$3, d2
move.l #$4, a0
bsr my_function
bra END

my_function:
    ; save d0-d2/a0 to the stack
    movem.l d0-d2/a0, -(sp)
    ; overwrite them inside the function
    move.l #$FF, d0
    move.l #$FF, d1
    move.l #$FF, d2
    move.l #$FF, a0
    ; restore from the stack, values are back
    movem.l (sp)+, d0-d2/a0
    rts
END:
```
