目录
其他资料:
https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md
RTFSC
运行第一个客户程序
第一个客户程序即文档所说的dummy.c
,键入命令后,会将dummy.c
编译成基于rv64指令的二进制格式文件(后缀名为 .bin),作为nemu模拟器的镜像文件(img_file)
make ARCH=$ISA-nemu ALL=dummy run
实现指令
首先查看反汇编结果,看看需要实现哪些指令
0000000080000000 <_start>:
80000000: 00000413 li s0,0
80000004: 00009117 auipc sp,0x9
80000008: ffc10113 addi sp,sp,-4 # 80009000 <_end>
8000000c: 00c000ef jal ra,80000018 <_trm_init>
0000000080000010 <main>:
80000010: 00000513 li a0,0
80000014: 00008067 ret
0000000080000018 <_trm_init>:
80000018: ff010113 addi sp,sp,-16
8000001c: 00000517 auipc a0,0x0
80000020: 01c50513 addi a0,a0,28 # 80000038 <_etext>
80000024: 00113423 sd ra,8(sp)
80000028: fe9ff0ef jal ra,80000010 <main>
8000002c: 00050513 mv a0,a0
80000030: 00100073 ebreak
80000034: 0000006f j 80000034 <_trm_init+0x1c>
通过查询手册,可以知道li
ret
等指令都是伪指令,比如第一条指令
80000000: 00000413 li s0,0
其十六进制内容为0x00000413
,对应二进制为0000 0000 0000 0000 0000 0100 0001 0011
,查询手册可知其为addi
指令,而当伪指令li
中的立即数小于4096时,的确会被编译器展开为addi
指令,因此目前可以确定,反汇编结果的右边的指令只是为了方便阅读(生成反汇编指令的代码在disasm.cc
中),我们在实现指令功能时,只需要看左边的十六进制内容即可
按照框架和文档提示,以及根据手册查询每条指令干了什么,然后填写代码即可
enum {
TYPE_I, TYPE_U, TYPE_S, TYPE_J,
TYPE_N, // none
};
#define immJ() do { *imm = SEXT(( \
(BITS(i, 31, 31) << 19) | \
BITS(i, 30, 21) | \
(BITS(i, 20, 20) << 10) | \
(BITS(i, 19, 12) << 11) \
) << 1, 21); Log(ANSI_FG_CYAN "%#lx\n" ANSI_NONE, *imm); } while(0)
static void decode_operand(Decode *s, int *dest, word_t *src1, word_t *src2, word_t *imm, int type) {
// ...
switch (type) {
// ...
case TYPE_J: immJ(); break;
}
}
static int decode_exec(Decode *s) {
// ...
INSTPAT("??????? ????? ????? 000 ????? 00100 11", addi , I, R(dest) = src1 + imm);
INSTPAT("??????? ????? ????? ??? ????? 11011 11", jal , J, s->dnpc = s->pc; s->dnpc += imm; R(dest) = s->pc + 4);
INSTPAT("??????? ????? ????? 000 ????? 11001 11", jalr , I, s->dnpc = (src1 + imm) & ~(word_t)1; R(dest) = s->pc + 4);
// ...
return 0;
}
标签:pa2,0000,sp,li,a0,指令,nju,addi
From: https://www.cnblogs.com/nosae/p/17066439.html