blob: 9ed447995185f1cb05946a7aa587d8372bf8994e [file] [log] [blame] [view] [edit]
# Assembly language in zxdb
## Disassembly
The `disassemble` command (`di` for short) disassembles from the current location. If available, the
instructions and call destinations are annotated with source line information:
```none {:.devsite-disable-click-to-copy}
[zxdb] di
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<>()
```
The `di` command can also accept an address or symbol as a parameter. If given a function name,
it disassembles the entire function:
```none {:.devsite-disable-click-to-copy}
[zxdb] di 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]
...
```
### Switches
The `disassemble` command accepts these switches:
* `--num=<lines>` or `-n <lines>`: The number of lines or instructions to emit. Defaults to the
instructions in the given function (if the location is a function name), or 16 otherwise.
* `--raw` or `-r`: Output raw bytes in addition to the decoded instructions.
## Stepping in machine instructions
Machine instructions can be stepped using the following Zxdb commands:
* `nexti` / `ni`: Step to the next instruction, stepping over function calls.
* `stepi` / `si`: Step the next instruction, following function calls.
For example:
```none {:.devsite-disable-click-to-copy}
[zxdb] ni
🛑 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] ni
🛑 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 a source-code
and shows that information on stepping or breakpoint hits. To switch to assembly-language mode,
type `disassemble`, and to switch back to source-code mode, type `list`.
## Registers
The `regs` command shows the most common CPU registers.
```none {:.devsite-disable-click-to-copy}
[zxdb] regs
General Purpose Registers
rax 0xfffffffffffffffa = -6
rbx 0x50b7085b
rcx 0x0 = 0
rdx 0x2023de8c87a0
rsi 0x7fffffffffffffff
rdi 0x50b7085b
rbp 0x224bb1e0b950
rsp 0x224bb1e0b928
...
```
There are other categories and options for CPU registers that can be shown by switches to the `regs`
command:
* `--all` or `-a`: Enable all register categories (does not imply `-e`).
* `--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. See below for more details.
* `--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.
### Registers in expressions
Registers can be used in [expressions](printing.md) like variables. The canonical name of a register
is `$reg(register name)`.
```none {:.devsite-disable-click-to-copy}
[zxdb] print $reg(x3)
79
```
In addition, the raw register name can be used if there is no variable with the same name:
```none {:.devsite-disable-click-to-copy}
[zxdb] print x3
79
```
Registers can be assigned using the normal expression evaluation syntax:
```none {:.devsite-disable-click-to-copy}
[zxdb] print x3 = 0
0
```
### 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 value and documentation, and
`set vector-format <new-value>` to set a new vector format. Possible values are:
* `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.
```none {:.devsite-disable-click-to-copy}
[zxdb] set vector-format double
[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`:
```none {:.devsite-disable-click-to-copy}
[zxdb] set vector-format float
[zxdb] print ymm1[0]
3.14159
```
When converting to an array, the low bits are assigned to be index 0, increasing from there.
Note that the vector register table in `regs` are displayed with the low values on the right side.