## `disassemble`

> [!NOTE]
> **Note:** This is the `disassemble` command. You can also use `di` to express `disassemble`.

The `disassemble` command disassembles from the current location. If available,
the instructions and call destinations are annotated with source line information:

For example:

    disassemble
    miscsvc.cc:118
     ▶ 0x20bc1c7aa60a  mov     dword ptr [rbx + 0x10c], eax
    miscsvc.cc:122
       0x20bc1c7aa610  movabs  rax, -0x5555555555555556
       0x20bc1c7aa61a  mov     qword ptr [rbx + 0xe8], rax
       0x20bc1c7aa621  mov     qword ptr [rbx + 0xe8], 0x0
       0x20bc1c7aa62c  mov     rdi, qword ptr [rbx + 0xb0]
       0x20bc1c7aa633  mov     rax, qword ptr [rbx + 0xe8]
       0x20bc1c7aa63a  mov     qword ptr [rbx + 0x20], rax
       0x20bc1c7aa63e  call    0x20d    ➔ std::__2::size<>()

### Functions

If you specify an address or symbol, the `disassemble` command disassembles on
the respective address or symbol. If you provide a function name, it
disassembles the entire function:

    disassemble main
    miscsvc.cc:88
       0x20bc1c7aa000  push    rbp
       0x20bc1c7aa001  mov     rbp, rsp
       0x20bc1c7aa004  push    rbx
       0x20bc1c7aa005  and     rsp, -0x20
       0x20bc1c7aa009  sub     rsp, 0x140
       0x20bc1c7aa010  mov     rbx, rsp
       0x20bc1c7aa013  mov     rax, qword ptr fs:[0x10]
       ...

### PC relative offsets

In some cases, you may want to disassemble based on the PC (program counter)
relative offset.

For example, to `disassemble` at the address `$rip - 0x7`:

> [!NOTE]
> **Note:** `$rip` is a register that stores a number (an address) of the next instruction to execute.

    [zxdb] di -- -0x7 # Disassemble at the address $rip - 0x7
         350     FX_LOGS(FATAL) << "Failed to construct the cobalt app: " << app.status();
         351   }
         352   inspector.Health().Ok();
         353   loop.Run();
       0x591e76352b  xor   edx, edx
       0x591e76352d  call  0x260fae   ➔ async::Loop::Run(async::Loop*, zx::time, bool)
         354   FX_LOGS(INFO) << "Cobalt will now shut down.";
     ▶ 0x591e763532  mov   edi, 0x30
       0x591e763537  call  0x81ab4    ➔ fuchsia_logging::ShouldCreateLogMessage(fuchsia_logging::LogSeverity)
       0x591e76353c  mov   byte ptr [rbp - 0x1b1], 0x0
       0x591e763543  test  al, 0x1
       0x591e763545  jne   0x2
       0x591e763547  jmp   0x74

### Arguments

The `disassemble` command accepts the following arguments:

- `--num=<lines>` or `-n <lines>`: The number of lines or instructions to emit.
  If the location is a function name, it defaults to the instructions in the
  given function. If the location is an address or symbol, it defaults to 16.

- `--raw` or `-r`: Output raw bytes in addition to the decoded instructions.

## Stepping in machine instructions

To step through machine instructions you can use following zxdb commands:

- `nexti` / `ni`: Advances to the next instruction, but steps over call
  instructions for the target architecture..

- `stepi` / `si`: Advances exactly one machine instruction..

For example:

    nexti
    🛑 main(int, const char**) • main.cc:102
    main.cc:99
     ▶ 0x23f711346233  mov   edx, 0x20
       0x23f711346238  call  0x35a3a3  ➔ __asan_memcpy
       0x23f71134623d  mov   rdi, qword ptr [rbx + 0x258]
       0x23f711346244  call  0x1677    ➔ $anon::DecodeCommandLine

    [zxdb] nexti
    🛑 main(int, const char**) • main.cc:102
    main.cc:99
     ▶ 0x23f711346238  call  0x35a3a3 ➔ __asan_memcpy
       0x23f71134623d  mov   rdi, qword ptr [rbx + 0x258]
       0x23f711346244  call  0x1677   ➔ $anon::DecodeCommandLine
       0x23f711346249  mov   rdi, qword ptr [rbx + 0x260]

Zxdb maintains information about whether the last command was an assembly
command or source-code and shows that information on stepping or breakpoint
hits.

To switch to assembly-language mode, use `disassemble`.

To switch to source-code mode, use `list`.

## `regs`

The `regs` command shows the most common CPU registers.

For example:

    regs
    General Purpose Registers
          rax  0xfffffffffffffffa = -6
          rbx          0x50b7085b
          rcx                 0x0 = 0
          rdx      0x2023de8c87a0
          rsi  0x7fffffffffffffff
          rdi          0x50b7085b
          rbp      0x224bb1e0b950
          rsp      0x224bb1e0b928
          ...

The `regs` command accepts the following arguments:

- `--all` or `-a`: Enable all register categories (does not imply `-e`).

- `--debug` or `-d`: Prints the debug registers.

- `--extended` or `-e`: Enables more verbose flag decoding. This enables more
  information that is not normally useful for everyday debugging. This
  includes information such as the system level flags within the `rflags`
  register for x64.

- `--float` or `-f`: Prints the dedicated floating-point registers. In most
  cases you should use `--vector` instead because all 64-bit ARM code and most
  x64 code uses vector registers for floating point.

- `--vector` or `-v`: Prints the vector registers.

### Registers in expressions

Registers can be used in [expressions](https://fuchsia.dev/fuchsia-src/development/debugger/expressions.md.txt) like variables. The
canonical name of a register is `$reg(register name)`.

For more information and examples, see [CPU registers](https://fuchsia.dev/docs/development/debugger/expressions#cpu-registers).

### Vector registers

The `regs --vector` command displays vector registers in a table according
to the current `vector-format` setting.

Use `get vector-format` to see the current values.

Use `set vector-format <new-value>` to set a new vector format.

The following values are supports:

- `i8` (signed) or `u8` (unsigned): Array of 8-bit integers.
- `i16` (signed) or `u16` (unsigned): Array of 16-bit integers.
- `i32` (signed) or `u32` (unsigned): Array of 32-bit integers.
- `i64` (signed) or `u64` (unsigned): Array of 64-bit integers.
- `i128` (signed) or `u128` (unsigned): Array of 128-bit integers.
- `float`: Array of single-precision floating point.
- `double`: Array of double-precision floating point. This is the default.

This example sets the `vector-format` to `double`:

    set vector-format double

This example returns the vector registers:

> [!NOTE]
> **Note:** The vector register table in `regs` are displayed with the low values on the right side.

    [zxdb] regs -v
    Vector Registers
      mxcsr 0x1fa0 = 8096

       Name [3] [2] [1]       [0]
       ymm0   0   0   0         0
       ymm1   0   0   0   3.14159
       ymm2   0   0   0         0
       ymm3   0   0   0         0
       ...

Vector registers can also be used like arrays in expressions. The
`vector-format` setting controls how each register is converted into an array
value.

For example, to show the low 32 bits interpreted as a floating-point value of
the x86 vector register `ymm1`:

1. Set the `vector-format` to float:

       set vector-format float

2. Print the vector register `ymm1`:

       [zxdb] print ymm1[0]
       3.14159

When converting to an array, the low bits are assigned to be index 0, increasing
from there.
[](https://issues.fuchsia.dev/issues/new?component=1439230&template=1881640&description=Issue+on:+https://fuchsia.dev/docs/development/debugger/assembly.md "Report a bug or suggest improvements on this page") [](https://cs.opensource.google/fuchsia/fuchsia/+/main:docs/development/debugger/assembly.md "View the source code of this page") [](https://ci.android.com/edit?repo=fuchsia/fuchsia/main&file=docs/development/debugger/assembly.md&cloneRepo=fuchsia/fuchsia:refs/heads/main&fullPath=fuchsia/docs/development/debugger/assembly.md "Edit the source code of this page")