MIT 6.1810 · Lab traps · 陷阱

Lab: 陷阱

本实验探讨如何使用陷阱实现系统调用。你将首先进行栈的热身练习,然后实现用户级陷阱处理。

难度:中等/困难

分支:traps

实验日期:2026 秋季

在开始编码之前,阅读xv6 手册的第 4 章,以及相关源文件:

$ git fetch
$ git checkout traps
$ make clean

RISC-V 汇编 简单

你的 xv6 仓库中有一个文件 user/call.c。make fs.img 编译它并生成程序的可读汇编版本 user/call.asm。

在 answers-traps.txt 中回答以下问题:

哪些寄存器包含函数的参数?例如,在 main 调用 printf 时,哪个寄存器保存 13?

在 main 的汇编代码中,对函数 f 的调用在哪里?对 g 的调用在哪里?(提示:编译器可能会内联函数)

函数 printf 位于什么地址?

在 main 中对 printf 的 jalr 之后,寄存器 ra 中的值是什么?

运行以下代码,输出是什么?

unsigned int i = 0x00646c72;
printf("H%x Wo%s", 57616, (char *) &i);

输出取决于 RISC-V 是小端序。如果 RISC-V 是大端序,你会将 i 设置为什么值以产生相同的输出?

在以下代码中,'y=' 之后会打印什么?为什么会发生这种情况?

printf("x=%d y=%d", 3);

Backtrace 中等

在 kernel/printf.c 中实现 backtrace() 函数。在 sys_pause 中插入对此函数的调用,然后运行 bttest。

backtrace:
0x0000000080002cda
0x0000000080002bb6
0x0000000080002898

一些提示:

Alarm 困难

你将向 xv6 添加一个功能,在使用 CPU 时间时定期提醒进程。添加一个新的 sigalarm(interval, handler) 系统调用。如果应用调用 sigalarm(n, fn),则在程序消耗每个 n 个 CPU "tick" 后,内核应该调用应用函数 fn。

$ alarmtest
test0 start
........alarm!
test0 passed
...
test3 passed
$ usertests -q
...
ALL TESTS PASSED

test0:调用处理程序

一些提示:

test1/test2()/test3():恢复中断的代码

你必须确保当警报处理程序完成后,控制返回到用户程序被定时器中断中断的指令。你必须确保寄存器内容恢复到中断时的值。

一些提示:

提交实验

时间花费

创建一个新文件 time.txt,放入一个整数,表示你花在实验上的小时数。

答案

将你的答案写在 answers-traps.txt 中。

提交

运行 make zipball,上传到 Gradescope。