是的,你是对的,在这种情况下,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 或a3。 rs1,寄存器源 1,在位 [9:7] 中,即 000。这映射到注册x8 或s0。
所以,总而言之,这条指令的实现意味着取rs1中存储的值,将其添加到零扩展的imm中,然后从内存中的该位置加载一个双字(64位)到@ 987654350@。对于指令0x5074,将224的立即数添加到寄存器x8的内容中,从内存中的结果地址中检索一个双字,并将值存储在寄存器x13中。