xv6 lab trap
Lab Trap #
- RISC-V assembly (easy)
- Backtrace (moderate)
- Alarm (hard)
RISC-V assembly (easy) #
Which registers contain arguments to functions? For example, which register holds 13 in main’s call to printf?
Ans: a1, a2 will store arguments. Here li a2,13 means that load immediate 13 to a2.
void main(void) {
  1c:	1141                	add	sp,sp,-16
  1e:	e406                	sd	ra,8(sp)
  20:	e022                	sd	s0,0(sp)
  22:	0800                	add	s0,sp,16
  printf("%d %d\n", f(8)+1, 13);
  24:	4635                	li	a2,13
  26:	45b1                	li	a1,12
	//...	
}
Where is the call to function f in the assembly code for main? Where is the call to g? (Hint: the compiler may inline functions.)
f() stored at 000000000000000e and g() stored at 0000000000000000.
0000000000000000 <g>:
// ...
int g(int x) {
	// ...
}
  // ...
000000000000000e <f>:
int f(int x) {
	// ...
}
At what address is the function printf located?
0000000000000616 <printf>:
We can also get the same result by looking at how compiler calculates address
auipc: add upper immediate to program counter and save to register
jalr: jump to certain address based on register and offset
30:	00000097          	auipc	ra,0x0
34:	5e6080e7          	jalr	1510(ra) # 616 <printf>
So the following steps are:
- program counter = 30
- add 0 to program counter and save to ra
- jump to ra + 1510: hex(1510) + 0x30 = 0x5e6 + 0x30 = 0x616
What value is in the register ra just after the jalr to printf in main?
Read risc-v-spec at page 16:
Register ra is used for return address. Therefore, jalr 1510(ra) ra store pc+4, 34 + 4 = 38.
Backtrace (moderate) #
void
backtrace(void)
{
  uint64 fp = r_fp();
  while(fp < PGROUNDUP(fp)) {
    uint64 ra = *(uint64*)(fp - 8); // return address at offset(-8)
    printf("%p\n", ra);
    fp = *(uint64*)(fp - 16); // previous frame pointer at offset(-16)
  }
}
Alarm (hard) #
TBD