RISC-Vアセンブリの練習
4649を出力するコード
code:4649.c
int min_caml_start(char *sp, char *hp) {
int i = 255;
min_caml_print_int(i);
}
code:sh
$ riscv32-unknown-elf-gcc -c 4649.c
$ riscv32-unknown-elf-gcc -c stub.c
$ riscv32-unknown-elf-gcc 4649.o stub.o
$ spike /opt/riscv/pk/riscv32-unknown-elf/bin/pk a.out
bbl loader
sp = 0x7ff0bb20, hp = 0x25a40
255
逆アセンブルする
code:sh
$ riscv32-unknown-elf-objdump -D 4649.o
4649.o: ファイル形式 elf32-littleriscv
セクション .text の逆アセンブル:
00000000 <min_caml_start>:
0: fd010113 add sp,sp,-48
4: 02112623 sw ra,44(sp)
8: 02812423 sw s0,40(sp)
c: 03010413 add s0,sp,48
10: fca42e23 sw a0,-36(s0)
14: fcb42c23 sw a1,-40(s0)
18: 0ff00793 li a5,255
1c: fef42623 sw a5,-20(s0)
20: fec42503 lw a0,-20(s0)
24: 00000097 auipc ra,0x0
28: 000080e7 jalr ra # 24 <min_caml_start+0x24>
2c: 00000013 nop
30: 00078513 mv a0,a5
34: 02c12083 lw ra,44(sp)
38: 02812403 lw s0,40(sp)
3c: 03010113 add sp,sp,48
40: 00008067 ret
spとfp(s0) の退避と復帰
こんな感じにspとfpを退避する(RISC-Vでは s0 が fp として使われる)
code:print_4649.S (asm)
.text
.globl min_caml_start
min_caml_start:
// スタックへ ra と fp(s0) を退避
addi sp, sp, -16
sw ra, 8(sp)
sw s0, 0(sp)
// 新しい fp(s0) を設定
addi s0, sp, 16
// (メイン処理)
// スタックから ra と fp(s0) を復帰
lw ra, 8(sp)
lw s0, 0(sp)
addi sp, sp, 16
ret
print_int の呼び出し
引数を a0 a1 a2 ... レジスタに渡して call min_caml_print_int を呼ぶ
code:print_4649.S (asm)
...
// 4649 を print する
li a0, 4649
call min_caml_print_int
...