NEMU PA1 菜鸡记录
闲话
NEMU是南大的一个课设,你天拿来当小学期任务,端地一番折磨
本篇博客由PA1实验报告改编而来,后续可能会有必做题的过程也可能没有
看阿瓜的懒惰程度了
实验进度表
任务序号 | 任务内容 | 完成情况 |
---|---|---|
必做任务1 | 实现正确的寄存器结构体 | 已完成 |
必做任务2 | 实现单步执行、打印寄存器、扫描内存 | 已完成 |
必做任务3 | 实现算术表达式的词法分析 | 已完成 |
必做任务4 | 实现算术表达式的递归求值 | 已完成 |
选做任务1 | 实现带有负数的算术表达式的求值 | 已完成 |
必做任务5 | 实现更复杂的表达式求值 | 已完成 |
选做任务2 | 实现指针解引用 | 已完成 |
必做任务6 | 实现监视点池的管理 | 已完成 |
必做任务7 | 实现监视点 | 已完成 |
必做题
思考题
思考题1 :opcode_table数组的类型
- opcode_table为helper_fun类型的数组,而helper_fun类型为指向参数类型为swaddr_t且返回值类型为int的函数指针,故opcode_table为函数指针数组。
思考题2
(1)要执行多久
- cpu_exec函数的参数是uint32_t,即无符号整型,而传入的-1因会导致溢出而成为最大的无符号整型数,保证能够执行完输入的所有指令。
(2)为什么要使用static
-
Q:框架代码中定义 wp_pool 等变量的时候使用了关键字 static,static 在此处的含义是什么? 为什么要在此处使用它?
-
A: static表示wp_pool为静态全局变量,此处使用static是为了避免wp_pool在程序运行中被误修改。
思考题3:读手册的方法
-
- Q: EFLAGS 寄存器中的 CF 位是什么意思
- A: 在目录中检索register和flag发现2.3.4.1节和附录c有提及相关内容,查阅得:CF为进位标志,如果运算导致最高位产生进位或者借位则为1.否则为0。
-
- Q: ModR/M 字节是什么
- A: 检索目录得ModR/M相关内容在17.2.1节,查阅可知ModR/M字节包括mod、reg、r/m三方面内容,分别表示索引类型或者寄存器编号、寻址模式编码等信息。
-
- Q: mov 指令的具体格式是怎么样的
- A: 检索目录在12.2.2.11节内找到mov指令相关内容,查阅可知格式为DEST←SRC
-
- shell命令:
find . -name “*[.h|.cpp]” | xargs wc -l
使用上述命令,得代码共129281行
- shell命令:
-
-
Make文件:
-Wall 使GCC产生尽可能多的警告信息,取消编译操作,打印出编译时所有错误或警告信息。
-Werror 要求GCC将所有的警告当成错误进行处理,从而终止编译操作。
使用-Wall和-Werror就是为了找出所有存在的或者潜在的错误,优化程序。
-
实验遇到的问题、思考、解决办法
-
在刚开始实验的时候,遇到“Makefile : “run”…”这种错误会不知所措,Prof Wei指点我要慢慢debug,通过Log、Assert等函数以及GDB等工具,最终解决了bug。
(GDB过于生疏,PA1完全靠肉眼debug) -
某次在虚仿平台关机导致git文件损坏,csdn、stackoverflow搜索到的办法都未能解决问题,最终在Wei老师的帮助下通过删除然后重新绑定远程仓库解决了问题。
-
打印寄存器时起初不知道如何依次打印,后来发现reg.h文件下有定义好的regsl数组和reg_l函数可以利用。
实验心得
-
要细读实验指导书,里面内容很详细,开始时候因为只看PPT导致忽略掉了很多细节内容。
-
调试程序时要善于使用gdb等工具,小型的bug可以使用Log、Assert等函数两面夹击来判断bug出现在哪里,总之对bug不要失措.
-
对于某任务中所用到的文件中的代码要通读一下,不求全看懂,多少知道相关函数、数组是做什么的,比如reg.h文件下的regsl数组和reg_l函数,
-
在.c文件中声明函数后要在.h文件中定义