auipc rd, imm20 (add upper immediate to pc):
add imm20 << 12 to the address of this instruction and write
the result in register rdjalr rd, imm12(rs) (jump and link register):
set pc to rs + imm12 (sign-extended, LSB cleared);
write pc + 4 to register rdjalr rs:
pseudoinstruction for jalr ra, 0(rs)ret: set pc to ra,
pseudoinstruction for jalr zero, 0(ra)call imm32 (usually with gcc -S):
PC-relative call with 32-bit offset,
pseudoinstruction for auipc ra, imm32_hi; jalr ra, imm32_lo(ra)long bar(long x)
{
return x;
}
long foo(long x)
{
return bar(x) + 1;
}
long main(void)
{
return foo(0) + foo(1);
}$ riscv64-unknown-elf-gcc -O -fno-omit-frame-pointer -mcmodel=medany -mno-relax -fno-pie -no-pie -fno-inline -o foo foo.c
$ riscv64-unknown-elf-objdump -d foo
...
0000000000010188 <bar>:
10188: 1141 addi sp,sp,-16
1018a: e422 sd s0,8(sp)
1018c: 0800 addi s0,sp,16
1018e: 6422 ld s0,8(sp)
10190: 0141 addi sp,sp,16
10192: 8082 ret
0000000000010194 <foo>:
10194: 1141 addi sp,sp,-16
10196: e406 sd ra,8(sp)
10198: e022 sd s0,0(sp)
1019a: 0800 addi s0,sp,16
1019c: 00000097 auipc ra,0x0
101a0: fec080e7 jalr -20(ra) # 10188 <bar>
101a4: 0505 addi a0,a0,1
101a6: 60a2 ld ra,8(sp)
101a8: 6402 ld s0,0(sp)
101aa: 0141 addi sp,sp,16
101ac: 8082 ret
00000000000101ae <main>:
101ae: 1101 addi sp,sp,-32
101b0: ec06 sd ra,24(sp)
101b2: e822 sd s0,16(sp)
101b4: e426 sd s1,8(sp)
101b6: 1000 addi s0,sp,32
101b8: 4501 li a0,0
101ba: 00000097 auipc ra,0x0
101be: fda080e7 jalr -38(ra) # 10194 <foo>
101c2: 84aa mv s1,a0
101c4: 4505 li a0,1
101c6: 00000097 auipc ra,0x0
101ca: fce080e7 jalr -50(ra) # 10194 <foo>
101ce: 9526 add a0,a0,s1
101d0: 60e2 ld ra,24(sp)
101d2: 6442 ld s0,16(sp)
101d4: 64a2 ld s1,8(sp)
101d6: 6105 addi sp,sp,32
101d8: 8082 ret
... .
.
.
+-> +----------------+ |
| | main's ra | |
| | previous s0/fp ----+
| | saved s1 |
| | ... |
| +----------------+ <-+
| | foo's ra @main | |
+---- previous s0/fp | |
+----------------+ |
.
.
.kernel/printf.c)
*(volatile int *)0 = 0; to exec() in kernel/exec.c &
run make qemu-tracevoid backtrace(uint64 fp) { ... } yourself-fno-omit-frame-pointerscause 0x000000000000000f
sepc=0x0000000080004d7c stval=0x0000000000000000
PANIC: kerneltrap
[<0x0000000080000594>] panic+0x46/0x62
[<0x000000008000292a>] kerneltrap+0xa8/0xcc
[<0x0000000080005dd4>] kernelvec+0x44/0x90
[<0x0000000080005bb6>] sys_exec+0xde/0x128
[<0x0000000080002b02>] syscall+0x3e/0x6c
[<0x00000000800027ec>] usertrap+0x6a/0x100stvec register (kernel/trap.c)stvecprintf("%d\n", *(volatile int *)0x4000000000); to main in user/call.c
sepc)lw instructionkernel/trampoline.S)usertrap in kernel/trap.c)scause: 13 (0xd), “load access fault”sepc: pc of the faulted instructionstval: the virtual memory addressusertrap in kernel/trap.c) to continue instead of killing the process?$ call
usertrap(): unexpected scause 0x000000000000000d pid=3
sepc=0x0000000000000028 stval=0x0000004000000000ecall instructionuser/usys.S, using a0-a6 as arguments and a7 as the syscall numberusertrap (kernel/trap.c) -> syscall (kernel/syscall.c), using a7 again to dispatch