CS61C | lecture8
R-Format Layout
在 RISC-V 中, 1 word = 4 Bytes = 32 bits.
将 32 位指令分为不同段
其中 opcode 为操作码,所有 R 类型寄存器的操作码都是 $0110011_2$
rs1 和 rs2 为源寄存器,rd 为目标寄存器
对于
1 | add x18, x19, x10 |
1 | add x4, x3, x2 |
则指令的正确编码为 $0021~ ~8233_{16}$
All RV32 R-format instructions
I-Format Layout
imm[11:0] 存储立即数,从 $-2048_{10} \sim +2047_{10}$
1 | addi x15, x1, -50 |
All RV32 I-format instructions
RISC-V Loads
Load Instructions 延用 I-Format Layout
1 | lw x14, 8(x2) |
All RV32 Loads instructions
其中,lbu 和 lhu 不执行符号扩展。
S-Format Layout
rs1 for base memory address, rs2 for data to be stored.
1 | sw x14, 8(x2) |
All RV32 S-format instructions
B-Format Layout
如果不执行分支
1 | PC = PC + 4 |
RISC-V 支持半字对齐,如果是 32 位 RISC-V 指令的任何给定字节地址 X,下一条指令将在内存中的地址 X + 4 处开始。如果使用 16 位的压缩指令时,PC 递增 2。
All RISC-V Branch instructions
U-Format Layout
lui: Load Upper Immediate
auipc: Add Upper Immediate to PC
LUI
LUI 会将立即数值写入目标寄存器的最高 20 位,并将最低 20 位清零。例如对于 0x87654321
1 | lui x10, 0x87654 # x10 = 0x87654000 |
但是对于
1 | lui x10, 0xDEADB # x10 = 0xDEADB000 |
对于 addi,它会进行符号位拓展,对于 0xEEF,由于最高位是 1,则前面 5 个半字节都会被扩展为 1。相当于对 0xDEADB 进行减 1。也就变成了 0xDEADA。
所以这种方法被淘汰了。解决方案就是直接使用指令 li。它会帮我们处理好。(Pre-increment value placed in upper 20 bits, if sign bit will be set on immediate in lower 12 bits.)
1 | li x10, 0xDEADBEEF |
AUIPC
Adds upper immediate value to PC and places result in destination register. Used for PC-relative addressing.
1 | Label: AUIPC x10, 0 # Puts address of Label in x10 |
J-Format Layout
jal saves PC + 4 in register rd(the return address). The way not to save the return address is to specify the rd as x0, which would discard the value stored there.
1 | j Label = jal x0, Label # Discard return address |
JALR Instruction (I-Format)
1 | jalr rd, rs, immediate |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Birdy の 小窝!
评论