南大计算机系统 PA¶
Warning
施工中!!! 如果你是南大修这门课的同学,不合适的内容已经折叠,请好自为之(不会真有 CS 专业的看一个遥感科学专业的人的学习记录吧)!学习是为自己学的,你在这里偷的懒将会马上在你的其他课程上让你付出代价。
前言¶
久闻南大系统 PA 的大名,想试试拓宽自己的知识面。然而作为非科班的学生,深知这一路上肯定会有不少艰难坎坷。近日终于鼓起勇气,开始了我的 PA 之路。将自己的经历记录于此,希望能勉励自己坚持下去,完成这 160+ 小时的编程任务。
PA0¶
由于个人能力和电脑配置不行(没法再分个磁盘出来了,其实还是畏难心理作祟吧)使用虚拟机进行实验。虚拟机有优点也有缺点,可保存快照,但是性能不行。而且也需要花一定的时间进行配置(感觉 ubuntu 也挺不错的,要不重装系统算了)。
后来参加一个编程比赛,最终还是强迫自己装了双系统,后续可能要东西放到自己的双系统上了
值得一提的是,我一开始虚拟器使用的是 22.04,但教程上是 20.04,有诸多不便。于是我又换成 20.04,但是换源总是失败。再一看 PA 指导,发现原来是我看的版本太旧了,又换回了 22.04,总之绕了很大的弯路,浪费了不少时间。
主要工作配置还是换源,安装一些包,顺便配置了下 Vim 的主题。中间需要编译 hello.c 并且试试 gdb(我属于那种有点基础但不多的人,还是老实去一步步来)。
获取源码的时候,主要有两个问题:
-
使用主机代理
虚拟机联网也是需要配置的,使用 NAT 模式,但是校园网的 IP 一直在变,只能用一次改一次了。
-
使用 SSH 验证身份
配置 SSH 是为了访问课程的代码仓库(必须要用 SSH),如果 SSH 密钥不是在默认位置的话,配置起来还挺麻烦。
初始化项目的时候,可能会提示缺什么包,可别像我一样眼瞎看不见报错。
在 PA0 里没有什么很难的地方,这部分除了配置环境外,最主要的目的就是为了让学生学会独立解决问题(RTFM STFW 和 RTFSC)
PA1¶
在开始愉快的PA之旅之前¶
运行红白机模拟器项目 FCEUX¶
-
ccache 环境变量
注意环境变量添加的位置(prepend)
-
编译用时
单线程编译用时 2 线程编译用时(-j2) ccache 使用 2 线程第一次编译用时(ccache -j2) ccache 使用 2 线程第二次编译用时(ccache -j2) 22.980s 11.581s 12.561s 2.303s
开天辟地的篇章¶
从状态机视角理解程序运行
(0, x, x) -> (1, 0, x) -> (2, 0, 0) -> (3, 0, 1) -> (4, 1, 1) -> (2, 1, 1) -> (3, 1, 2) -> (4, 3, 2) -> (2, 3, 2) -> ... -> (3, 4851, 99) -> (4, 4950, 99) -> (2, 4950, 99) -> (3, 4950, 100) -> (4, 5050, 100) -> (5, 5050, 100) -> ...
RTFSC¶
思考:为什么全部都是函数?
这是你的思考题,不是我的思考题。这个问题我觉得应该不需要我说。
思考:这些参数是从哪里来的呢?
如果你用 gdb 查看了 argc
和 argv
参数的内容,你会发现它们代表的含义与参数内容(对这个理解比较深入的会知道 argv
的第一个参数是什么)。程序内参数的传递是从 main
函数开始的,其 main
函数的参数是在执行时从外部传递的。具体在从哪里传递的,你可以想想程序是由什么启动的,那里会有参数的内容,刚好能对上号。
用 gdb 进行调试,但不知道怎么开始?看看 scripts
文件夹里的脚本吧。此外,关于调试的 PPT:调试:理论与实践——王慧妍老师
思考:究竟要执行多久?
函数参数已经给出了答案,将 -1 赋值给 uint64_t n
,将会得到一个很大的值,理论上应该会执行很久,因为 execute
函数中 n
作为计数变量到达 0 时才会结束函数内的循环。
然而实际上在客户程序中会通过 set_nemu_state
改变 nemu_state.state
从而导致 execute
执行结束。
谁来指示程序的结束?
(施工中)
优美地退出
当在 NEMU 中未执行 c
命令就按 q
退出时,会输出报错信息。经过调试,容易发现问题出在 is_exit_status_bad
函数中,在条件表达式中,执行 c
会使得 (nemu_state.state == NEMU_END && nemu_state.halt_ret == 0)
分支为真(具体发生了什么可以去 decode_exec
中一探究竟)
而直接退出时,nemu_state.state
为初始值 NEMU_STOP
没有发生改变。不满足 is_exit_status_bad
中的条件表达式, good
为 false
。
想要优美地退出,需要让 q
退出时满足 is_exit_status_bad
中的条件表达式,已经有一个分支处理了 (nemu_state.state == NEMU_QUIT)
的情况,只需要满足这个情况即可。