是的,你是对的,在这种情况下,offset 和 immediate 本质上是一回事。在 RISC-V ISA 中,您会看到内存操作(加载和存储)的立即数被称为“偏移量”,因为它们的使用方式——它们被添加到寄存器中保存的值rs1
以导出最终内存从/存储到的地址,因此可以将它们视为与rs1
.
特别是在C.LD
(压缩加载双字)指令的情况下,您可以将立即数视为八位长的无符号数,位索引为 0 到 7。这些位分布在指令中的两个位置,以便rd
和rs1
字段可以跨指令类型位于相同的位位置。(这显然有点令人困惑,但它使硬件更容易实现。)立即数的最后三位(索引为 0、1 和 2 的位)未编码,因为它们是假定为 0 - 双字的字节地址假定为双字(64 位 / 8 字节)对齐,这意味着它必须能被 8 整除。
为了更清楚一点,因为您询问了如何实施指令,例如,让我分解指令0x5074
:
| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
立即数来自位 [6:5|12:10]。位 [12:10] 代表立即数的第 5、4 和 3 位,位 [6:5] 代表立即数的第 7 位和第 6 位。在这种情况下,即100
和11
。那只有 5 位,所以整个立即数变成了11100000
- 我们为立即数的第 2、1 和 0 位插入 0。立即数是零扩展的,所以它变成0x0000_00e0
, 或224
十进制。(注意零扩展——许多 RISC-V 立即数,包括标准加载字指令,都是符号扩展的)。
我知道你的问题是专门关于即时的,但如果它有用的话,至于指令的其余部分:
这里的位 [1:0] 是操作码,00
. 这是压缩指令操作码之一(非压缩指令有 7 位操作码,位 [1:0] 是11
)。位 [15:13]010
是 C.LD 指令的操作码。
rd
,寄存器目标,在位 [4:2] 中,在这种情况下是101
。如果我们查看压缩指令寄存器映射表,我们会看到这意味着寄存器目标是x13
or a3
。rs1
,寄存器源 1,在位 [9:7] 中,即 000
. 这映射到注册x8
或s0
。
因此,总而言之,该指令的实现意味着获取存储在 中的值rs1
,将其添加到imm
零扩展的 中,然后将内存中该位置的双字(64 位)加载到 中rd
。对于指令0x5074
,立即数 224 被添加到 register 的内容中x8
,从内存中的结果地址中检索一个双字,并将值存储在 register 中x13
。