Lab4
RISC-V assembly
1.
(1)s0
(2)a2
2.
li a1,12 函数内联
3.
0x630
4.
0x630
5.
HE110 World
i改为0x726c6400,still 57616
6.
y的结果取决于之前a2中保存的数据Backtrace(moderate)

Alarm(Hard)
Last updated
1.
(1)s0
(2)a2
2.
li a1,12 函数内联
3.
0x630
4.
0x630
5.
HE110 World
i改为0x726c6400,still 57616
6.
y的结果取决于之前a2中保存的数据
Last updated
void
backtrace()
{
printf("backtrace:\n");
uint64 fp = r_fp(),top = PGROUNDUP(fp);
// 因为risc-v中栈是向下增长的,所以上一个Frame肯定在这一个Frame的上面
// 所以以top为边界增长,取出 To Prev.Frame,然后获取 fp-8 中存的返回地址。
for(;fp < top;fp=*(uint64*)(fp-16)) {
uint64 ret = *(uint64*)(fp-8);
printf("%p\n",ret);
}
} int interval; // 时间间隔
void (*handler)(); // 处理函数
int counts; // 滴答时长
int doing; // 防止对处理程序的重复调用——如果处理程序还没有返回,内核就不应该再次调用它。test2测试这个。
struct trapframe *alarm_trapframe; // 用来保存寄存器,方便再 sigreturn 中恢复if(which_dev == 2){
if (++p->counts == p->interval && p->doing == 0) {
p->doing = 1;
memmove(p->alarm_trapframe,p->trapframe,sizeof(struct trapframe));
p->trapframe->epc = (uint64) p->handler;
p->counts = 0;
}
yield();
}uint64
sys_sigalarm(void)
{
// a0 是第一个参数的寄存器,a1是第二个参数的寄存器
if (argint(0,&myproc()->interval) < 0 || argaddr(1,(uint64 *)&myproc()->handler) < 0)
{
return -1;
}
return 0;
}
uint64
sys_sigreturn(void)
{
// 恢复寄存器状态
memmove(myproc()->trapframe,myproc()->alarm_trapframe,sizeof(struct trapframe));
myproc()->doing = 0;
return 0;
}p->interval = 0;
p->handler = 0;
p->counts = 0;
p->doing = 0;
if((p->alarm_trapframe = (struct trapframe *)kalloc()) == 0) {
release(&p->lock);
return 0;
}if(p->alarm_trapframe)
kfree((void*)p->alarm_trapframe);
p->doing = 0;
p->handler = 0;
p->interval = 0;
p->counts = 0;