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