1.1

单步执行

单步执行的功能十分简单, 而且框架代码中已经给出了模拟CPU执行方式的函数, 你只要使用相应的参数去调用它就可以了. 如果你仍然不知道要怎么做, RTFSC

我们从源代码可以看到这个,通过查看c(继续执行发现)他条用了一个exec函数,我们的目的,就是通过求职,得到那个数字是多少,然后调用exec这个函数,如何得到数字,使用strtok进行得到,之后得到的是char,转换需要使用atoi来进行使用

代码如下:

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中的输出

通过这个可以知道,我们需要使用打印寄存器,只需要调用isa——display,因为我们选择的是riscv,所以我们需要在,make menuconfig里面选择isa,同事也要去对应的架构下面完善这个打印函数,这个打印函数还要输出数字,这个数值,是使用gdr这个api得到的,这个在头文件里有定义

代码如下

1

扫描内存

扫描内存的实现也不难, 对命令进行解析之后, 先求出表达式的值. 但你还没有实现表达式求值的功能, 现在可以先实现一个简单的版本: 规定表达式EXPR中只能是一个十六进制数, 例如

1
x 10 0x80000000

这样的简化可以让你暂时不必纠缠于表达式求值的细节. 解析出待扫描内存的起始地址之后, 就可以使用循环将指定长度的内存数据通过十六进制打印出来. 如果你不知道要怎么输出, 同样的, 你可以参考GDB中的输出. 问题是, 我们要如何访问客户计算机的内存数据呢? (答案早就说了喂)

实现了扫描内存的功能之后, 你可以打印0x80000000或者0x100000附近的内存, 你应该会看到程序的代码, 和内置客户程序的内容进行对比, 检查你的实现是否正确.

刚开始没有看懂题目意思,主要是使用,后面这个地址,来得到后10位地址的指,一个地址有4B,因此800下一个就是804,夹具体调用的函数是vaddr——read(addr,len),这个len是字节长度,写4就是4B,暂时是固定所有制来进行执行的

代码如下

1