You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.9 KiB
Markdown
75 lines
2.9 KiB
Markdown
# Using the debugger
|
|
|
|
You are launched into the debugger either by an `ebreak/sbreak` instruction, or when an exception occurs while running executing instructions.
|
|
|
|
Consider the example programm `examples/fibs.asm`:
|
|
|
|
```asm riscv-asm
|
|
.data
|
|
fibs: .space 56
|
|
|
|
.text
|
|
main:
|
|
addi s1, zero, 0 ; storage index
|
|
addi s2, zero, 56 ; last storage index
|
|
addi t0, zero, 1 ; t0 = F_{i}
|
|
addi t1, zero, 1 ; t1 = F_{i+1}
|
|
ebreak ; launch debugger
|
|
loop:
|
|
sw t0, fibs(s1) ; save
|
|
add t2, t1, t0 ; t2 = F_{i+2}
|
|
addi t0, t1, 0 ; t0 = t1
|
|
addi t1, t2, 0 ; t1 = t2
|
|
addi s1, s1, 4 ; increment storage pointer
|
|
blt s1, s2, loop ; loop as long as we did not reach array length
|
|
ebreak ; launch debugger
|
|
; exit gracefully
|
|
addi a0, zero, 0
|
|
addi a7, zero, 93
|
|
scall ; exit with code 0
|
|
```
|
|
|
|
This calculates the fibonacci sequence and stores it in memory at `fibs`. before and after it calculated all fibonacci numbers, it
|
|
uses the `ebreak` instruction to open the debugger. Let's run it and see what happens:
|
|
|
|
```
|
|
> python -m riscemu examples/fibs.asm
|
|
[MMU] Successfully loaded: LoadedExecutable[examples/fibs.asm](base=0x00000100, size=72bytes, sections=data text, run_ptr=0x00000138)
|
|
[CPU] Started running from 0x00000138 (examples/fibs.asm)
|
|
Debug instruction encountered at 0x0000013C
|
|
>>>
|
|
```
|
|
|
|
In this interactive session, you have access to the cpu, registers, memory and syscall interface. You can look into everything,
|
|
and most common tasks should have helper methods for them.
|
|
|
|
**Available objects are:**
|
|
|
|
* `mem`: (aka `mmu` or `memory`)
|
|
* `dump(address, fmt='hex', max_rows=10, group=4, bytes_per_row=16, all=False`:
|
|
Dumps the memory at `address`, in at most `max_rows` rows, each containing `bytes_per_row` bytes grouped
|
|
into groups of `group` bytes. They can be printed as:
|
|
* `hex`: hexadecimal, unsigned
|
|
* `int`: converted to integers
|
|
* `uint`: converted to unsigned integers
|
|
* `symbol(name)`: Lookup all symbols named `name`
|
|
* `reg`: (aka `regs` or `registers`)
|
|
* `dump(full=False)` dumps all integer registers (unless `all` is true, then all registers are printed)
|
|
* `get(name)` get register content
|
|
* `set(name, val)` set register content
|
|
* `cpu`:
|
|
* The CPU has the `pc` attribute and `cycle` attribute. Others won't be useful in this context.
|
|
|
|
**Available helpers are:**
|
|
|
|
* `dump(regs | addr)` dumps either registers or memory address
|
|
* `cont(verbose=False)` continue execution (verbose prints each executed instruction)
|
|
* `step()` run the next instruction
|
|
* `ins()` get current instruction (this reference is mutable, if you want to edit your code on the fly)
|
|
* `run_ins(name, *args)` Run an instruction in the current context. Symbols, jumping, etc are supported!
|
|
|
|
|
|
Example:
|
|
|
|
![debuggin the fibs program](debug-session.png)
|