第 7 章:算术逻辑指令
学习目标
- 实现 R 型和 I 型指令
- 理解算术运算
- 掌握逻辑运算
7.1 思考:最简单的指令是什么?
你觉得哪条指令最简单?
答案可能是 add:
add x1, x2, x3 # x1 = x2 + x3
就是简单的加法!但实现起来有细节。
7.2 R 型指令格式
add rd, rs1, rs2 # rd = rs1 + rs2
sub rd, rs1, rs2 # rd = rs1 - rs2
and rd, rs1, rs2 # rd = rs1 & rs2
问题:add 和 sub 的 opcode 一样吗?
是的!都是 0x33。那怎么区分?
答案:看 funct7 和 funct3!
add: funct7=0x00, funct3=0x0
sub: funct7=0x20, funct3=0x0
7.3 实现 R 型指令
void exec_R_type(Decode d) {
uint32_t src1 = reg_read(d.rs1);
uint32_t src2 = reg_read(d.rs2);
uint32_t result;
switch (d.funct3) {
case 0x0: // ADD/SUB
if (d.funct7 == 0x00) {
result = src1 + src2; // ADD
} else {
result = src1 - src2; // SUB
}
break;
case 0x7: // AND
result = src1 & src2;
break;
// ...
}
reg_write(d.rd, result);
}
问题:为什么不用 int 而用 uint32_t?
因为 RISC-V 寄存器是 32 位无符号数!
7.4 I 型指令
addi x1, x2, 10 # x1 = x2 + 10
问题:addi 和 add 有什么区别?
一个用立即数,一个用寄存器!
void exec_I_type(Decode d) {
uint32_t src1 = reg_read(d.rs1);
uint32_t result = src1 + d.imm;
reg_write(d.rd, result);
}
7.5 移位指令的陷阱
slli x1, x2, 5 # x1 = x2 << 5
问题:移位 5 位,立即数是 5 吗?
是的!但只用低 5 位(因为最多移 31 位)。
case 0x1: // SLLI
result = src1 << (d.imm & 0x1F);
break;