「palab03」基础设施-简易调试器
基础设施
大概是半个月前实现了表达式求值, 之后就一直搁置了PA实验, 现在慢慢捡起来
之前实现表达式求值的时候发现无法调试, 然后才发现自己直接跳过了「基础设施」这一步直接开始写表达式求值了。。。
现在把之前的基础设施部分补一下
大概就是要在monitor/debug
下实现一些简单的命令解析功能
照着文档来写就ok了
命令 | 格式 | 使用举例 | 说明 |
---|---|---|---|
帮助(1) | help |
help |
打印命令的帮助信息 |
继续运行(1) | c |
c |
继续运行被暂停的程序 |
退出(1) | q |
q |
退出NEMU |
单步执行 | si [N] |
si 10 |
让程序单步执行N 条指令后暂停执行, 当N 没有给出时, 缺省为1 |
打印程序状态 | info SUBCMD |
info r info w |
打印寄存器状态 打印监视点信息 |
扫描内存(2) | x N EXPR |
x 10 $esp |
求出表达式EXPR 的值, 将结果作为起始内存 地址, 以十六进制形式输出连续的N 个4字节 |
表达式求值 | p EXPR |
p $eax + 1 |
求出表达式EXPR 的值, EXPR 支持的 运算请见调试中的表达式求值小节 |
设置监视点 | w EXPR |
w *0x2000 |
当表达式EXPR 的值发生变化时, 暂停程序执行 |
删除监视点 | d N |
d 2 |
删除序号为N 的监视点 |
解析命令可能用到的api:
strtok
readline
sscanf
单步执行
单步执行的功能十分简单, 而且框架代码中已经给出了模拟CPU执行方式的函数, 你只要使用相应的参数去调用它就可以了. 如果你仍然不知道要怎么做, RTFSC.
「框架代码中已经给出了模拟CPU执行方式的函数」:
nemu/src/isa/$ISA/exec/exec.c
中定义的isa_exec_once()
:
参考给出的cmd_c
的实现:
1 |
|
1 |
|
注意到这里的cpu_exec(-1)
之前「palab01」中已经提到过
传入-1相当于无限执行, 那么我们传入N就相当于执行N次了
这样一来, 单步执行便实现了
我这里的思路历程:
框架代码? 找到RTFSC一章->找到
isa_exec_once
->想到不会要自己调用这个吧->想到给出了继续执行的封装->原来可以直接调用更上层的封装所以还是要好好理解代码啊
如何将*args
转换为数字并保证一定的鲁棒性? 用sscanf
我的实现:
1 |
|
打印程序状态
打印寄存器就更简单了. 不过既然寄存器的结构是ISA相关的, 我们希望能为简易调试器屏蔽ISA的差异. 框架代码已经为大家准备了如下的API:
1
2
// nemu/src/isa/$ISA/reg.c
void isa_reg_display(void);执行
info r
之后, 就调用isa_reg_display()
, 在里面直接通过printf()
输出所有寄存器的值即可. 如果你从来没有使用过printf()
, 请RTFM或者STFW. 如果你不知道要输出什么, 你可以参考GDB中的输出.
首先阅读一下:reg.c
1 |
|
emm..我确实不知道要输出什么..
在gdb中使用info registers
打印出类似如下格式的结果
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!