PA1:监视器相关

监视器这一章节,所需的代码都在nemu/src/monitor/sdb下,修改也是集中在这里修改,讲义讲的有点模糊,所以我直接写在这里。

 

相比于scanf ,sscanf可以从字符串中读取内容。   比如char str[]="123 4.567  yes"   sscanf就可以sscanf("%d %lf %s",&a,&b,&c)

我看了sdb.c的源文件,cmd_c cmd_q cmd_help  分别对应了已经支持的三个按键功能  ,按照表格,内存监视已经实现,但是这里没有写入。此外上面的 rl_gets函数应该对应的是命令扫描。

这一章节的任务是实现表格中间的三项:单步执行、扫描内存和打印寄存器。

首先改的是打印寄存器,在cmd_table里按上面的格式增加对应项,然后在cmd_q下面再增加函数cmd_print_status,里面引用isa/riscv64下的isa_reg_display函数,但是这个函数也需要自己实现。只在sdb.c里加个套壳是没用的,官方只给了api的壳子。

实现也很简单,reg.c里面已经定义了32个寄存器名字,直接逐个printf就行:

void isa_reg_display()
{
    int i=0;
    for(i=0;i<32;i++)
    {
        printf("%s:%d\t",regs[i],cpu.gpr[i]);
    //这一行第二个参数用%p搭配regs[i]应该也可以    
        if(i%4==3)  pritnf("\n");
    }
}

7/8补充:PA1实现的sdb和gdb一样是调试器,只不过功能更简单。这一阶段多实现一些功能,后面处理起来也会方便很多。比如这里要求实现32个寄存器,但在实际使用时,还需要PC寄存器,这个也很常用。

/////////////      一个.c文件直接include自己对应的.h文件,表示直接引用.h中的已经定义好的宏,这样就不需要再定义一遍。

 

  然后是单步执行,表格里要求要实现任意步,但这里暂时只实现一步。  对应函数应该就是src/cpu内的cpu-exec.c文件,里面分别定义了exec_one、execute和cpu_exec三个函可能相关的函数数,分别对应执行一次和多次。但这个写了以后我还没想到应该怎么样验证。考虑到cmd_c里面用的是cpu_exec(-1),那我就在单步执行里用cpu_exec(1).  

  这里没有考虑输入参数的问题,如果还考虑输入参数,那么还需要对args进行转换、判断。

 

  然后是扫描内存,关于扫描内存,这个我确实没有什么过多思路,顺着monitor.c找到了memory/paddr.c里面的,又在isa.h里进行了查找,我猜isa.h的 isa_mmu_check可能是我需要的函数,但我还不是很确定。所以先调用试了一下,但是类型这一点我不确定应该用什么。paddr.c里面有omem_read这样的函数,但这似乎是读取的主机内存。

  依次尝试了一下,vaddr_read()不可以,paddr_read()的作用范围不包含0x100000, isa_mmu_check()也不行。

  最后换了个思路,我在单步执行里调用了cpu_exe()这个函数,在使用这个命令时,也会报出当前地址向后四个字节的内容。所以可能应该在exec_once()这个函数里找内存访问。我打算直接在cpu-exec.c里另写一个函数来实现效果。

 

 

 

 

此外,我在paddr.c里面看到了似乎是访客内存和主机内存的转换函数。

另注,这几个函数都需要用int 型,因为都需要返回值,用void会导致编译器提示指针类型不符。

cpu_exec()这个函数的基本内容,就是执行execute(n),然后检查当前的nemu状态,如果是running,说明还碰到断点或结尾,那么就赞同,否则直接进入终端并print提示。

想要输出结果和自带的一样提示代码行,就用封装好的Log而不是printf

 

posted @ 2024-02-03 09:10  namezhyp  阅读(23)  评论(0编辑  收藏  举报