南京大学 计算机系统基础 课程实验 2022

实验网站2020 南京大学计算机系统基础习题课

PA0 - 世界诞生的前夜: 开发环境配置

使用 vimtutor 命令启动 vim 教程。

教程:GNU/LinuxMakefileGDBtmuxGitLinux C编程一站式学习

课程:The Missing Semester of Your CS Education

其他:Visualizing Git Concepts with D3

使用 apt-get install 经常遇到 “The following packages have unmet dependencies” 错误,原因是因为依赖的包和现有的包版本冲突,之前我都是手动 apt-get remove,但是经常遇到该问题。STFW 之后,这里推荐的 aptitude 工具比较方便,发生冲突时会询问是否降级。(apt-getaptitudeapt 的区别,是否有必要使用 aptitude讨论。)

使用 make 经常遇到 “No such file or directory” 之类缺失头文件的错误,目前是遇到两种情况。一种是缺失对应的包,直接 apt-get install 即可解决;另一种是有对应的包,但是当前项目中 .mk 文件配置的程序名称和现有名称不一致(例如,配置的是 llvm-config,而现有的是 llvm-config-11),修改 .mk 文件即可解决。

PA1 - 开天辟地的篇章: 最简单的计算机

手册:riscv-isa-manualriscv-elf-psabi-docetcNEMU ISA API

可以在目标命令之前添加 time 命令,从而计算目标命令的执行时间。使用 make 命令的 -j 选项,可以启用多线程编译。make -j4 表示创建 4 个线程并行编译,具体创建多少个线程,可以根据 lscpu 命令查询得到的系统中的 CPU 数量来确定。使用 ccache 工具可以缓存目标文件,从而加速执行 make clean 之后,再次执行 make 的速度。

如何实现宏 IFDEFMUXDEF。其中 IFDEF 表示,如果定义了 CONFIG_DEVICE 宏,才会调用 init_device() 函数。而 MUXDEF 表示,如果定义了 CONFIG_TRACE 宏,则预处理结果为 ON,否则预处理结果为 OFF

1
2
IFDEF(CONFIG_DEVICE, init_device());
MUXDEF(CONFIG_TRACE, "ON", "OFF")

nemu/include/macro.h 文件中有如下定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// macro concatenation
#define concat_temp(x, y) x ## y
#define concat(x, y) concat_temp(x, y)

// macro testing
// See https://stackoverflow.com/questions/26099745/test-if-preprocessor-symbol-is-defined-inside-macro
#define CHOOSE2nd(a, b, ...) b
#define MUX_WITH_COMMA(contain_comma, a, b) CHOOSE2nd(contain_comma a, b)
#define MUX_MACRO_PROPERTY(p, macro, a, b) MUX_WITH_COMMA(concat(p, macro), a, b)

// define placeholders for some property
#define __P_DEF_0 X,
#define __P_DEF_1 X,

// define some selection functions based on the properties of BOOLEAN macro
#define MUXDEF(macro, X, Y) MUX_MACRO_PROPERTY(__P_DEF_, macro, X, Y)

// simplification for conditional compilation
#define __IGNORE(...)
#define __KEEP(...) __VA_ARGS__

// keep the code if a boolean macro is defined
#define IFDEF(macro, ...) MUXDEF(macro, __KEEP, __IGNORE)(__VA_ARGS__)

我们可以使用如下代码进行测试,同时给出宏展开的步骤。需要注意的是,只有当 CONFIG_DEVICE 被定义为 0 或 1 时,才会执行函数调用。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

#define CONFIG_DEVICE 1

void init_device() {
printf("Hello, Linux World!\n");
}

int main(void) {
IFDEF(CONFIG_DEVICE, init_device());
return 0;
}
1
2
3
4
5
6
7
8
9
10
IFDEF(CONFIG_DEVICE, init_device());
IFDEF(1, init_device());
MUXDEF(1, __KEEP, __IGNORE)(init_device());
MUX_MACRO_PROPERTY(__P_DEF_, 1, __KEEP, __IGNORE)(init_device());
MUX_WITH_COMMA(concat(__P_DEF_, 1), __KEEP, __IGNORE)(init_device());
MUX_WITH_COMMA(__P_DEF_1, __KEEP, __IGNORE)(init_device());
MUX_WITH_COMMA(X,, __KEEP, __IGNORE)(init_device());
CHOOSE2nd(X, __KEEP, __IGNORE)(init_device());
__KEEP(init_device());
init_device();
作者

Ligh0x74

发布于

2024-08-12

更新于

2024-08-18

许可协议

评论