RV32I控制转移指令的偏移量计算问题

Posted snsn1984

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RV32I控制转移指令的偏移量计算问题相关的知识,希望对你有一定的参考价值。

RV32I的控制转移指令可以分为无条件跳转(unconditional jumps)和条件分支(conditional branches)。其中,无条件跳转(unconditional jumps)包含JAL和JALR;条件分支(conditional branches)包含BEQ、BNE、BLT、BLTU、BGE和BGEU。这些控制转移指令会根据指令所带的立即数(imm)去计算跳转地址的偏移量,而这个偏移量的计算在这里有两种方式。

第一种偏移量计算方式:实际偏移量 = 立即数(imm)* 2

除了JALR之外的所有RV32I的控制转移指令,即:JAL、BEQ、BNE、BLT、BLTU、BGE和BGEU,都采用这种计算方式。在RV32I的规范中可以找到对应的内容。

JAL 规范P20

JAL 规范P21

条件分支(BEQ、BNE、BLT、BLTU、BGE和BGEU) 规范P22

这些指令在规范中都提到,立即数(imm)表达的是乘以2byte的偏移量,又因为RISCV的地址是byte地址,所以通过立即数(imm)来取偏移量的时候,就需要对立即数(imm)乘以2。

实际例子1

《COMPUTER ORGANIZATION AND DESIGN(RISC-V EDITION)》 P115

这里的偏移量是十进制的2000,那么对应的立即数(imm)是1000,所以指令中的立即数(imm)是1111101000,=2(10)- 1 - 2(4)- 2(2)- 2(1)- 1 = 1000.

实际例子2

《COMPUTER ORGANIZATION AND DESIGN(RISC-V EDITION)》 P116-117

以bne指令为例,它要跳转到最后的Exit,对应到具体的地址就是80024,而bne的指令位置是80012,将80012中的bne指令中的立即数(imm)按照指令格式拼接起来,实际上立即数是0110,也就是6。6 * 2 + 80012 = 80024。

根本原因

这些指令通过以2byte作为立即数(imm)的基本单位来计算偏移量,是为了达到通过有限的立即数(imm)可以表达更大的偏移量。那么为什么以2byte(halfword)来作为单位,不干脆直接以4byte(word)作为基本单位?这是因为RISCV的C扩展,即压缩指令扩展,是16位的。在这种情况下,只能选择2byte(halfword)来作为单位,用4byte(word)作为单位会导致有些指令的地址无法被跳转到。

《COMPUTER ORGANIZATION AND DESIGN(RISC-V EDITION)》 P116中有相关的讲解:

第二种偏移量计算方式:实际偏移量 = 立即数(imm)

采用这种计算方式的RV32I的控制转移指令,只有JALR指令。RV32I的规范中,有专门提到:

规范 P21

这里专门提到了12位的imm直接加上rs1,就可以获取目标地址。同时,规范中也专门用一段话来讲这个问题。

规范 P21

总结

在对RV32I控制转移指令的偏移量计算问题进行分析之后,将这些指令按照类型进行分类,可以得到如下:

  1. JAL J类型
  2. BEQ、BNE、BLT、BLTU、BGE和BGEU B类型
  3. JALR I 类型

所以,我们也可以将这个计算按照指令类型进行划分,J类型和B类型的指令是需要对立即数(imm)乘以2来计算实际偏移量,而I类型的指令则不需要。

RV64I是在RV32I的基础之上直接使用控制转移指令的,所以这个计算问题在RV64I中也同样存在。

 

注:RISCV规范指的是

以上是关于RV32I控制转移指令的偏移量计算问题的主要内容,如果未能解决你的问题,请参考以下文章

RV32I控制转移指令的偏移量计算问题

RV32I控制转移指令的偏移量计算问题

RV32I控制转移指令的偏移量计算问题

RV32I指令集

关于汇编的段内转移

汇编指令JMP是啥意思?