Assembly RiscV跳转(j,jal)到错误地址(通过偏移量2关闭)

Assembly RiscV跳转(j,jal)到错误地址(通过偏移量2关闭),assembly,riscv,Assembly,Riscv,我使用的是riscV处理器(RV32)。我在上面写了一些代码,发现了一些奇怪的东西。当我使用“JAL”指令或“J”指令跳转到特定地址时,似乎偏移量计算不正确 假设我有一些代码(PRAM_ResetVector)位于地址0x00008080,我想跳转到该地址 跳转代码在程序集“jal x1,PRAM_ResetVector”中如下所示,位于地址0x000085e8处。指令编码(risc32)如下所示0xeff09fa9 然而,在执行跳转指令后发生的情况是,我在地址0x00008082而不是预期的0

我使用的是riscV处理器(RV32)。我在上面写了一些代码,发现了一些奇怪的东西。当我使用“JAL”指令或“J”指令跳转到特定地址时,似乎偏移量计算不正确

假设我有一些代码(PRAM_ResetVector)位于地址0x00008080,我想跳转到该地址

跳转代码在程序集“jal x1,PRAM_ResetVector”中如下所示,位于地址0x000085e8处。指令编码(risc32)如下所示0xeff09fa9

然而,在执行跳转指令后发生的情况是,我在地址0x00008082而不是预期的0x00008080处着陆

我似乎找不到原因,有人能帮忙吗?

指令是“0xeff09fa9”?这32位实际上是两个不同的双字节指令,c.sd和c.addw

指令是“0xeff09fa9”?这32位实际上是两个不同的双字节指令,c.sd和c.addw

so:
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    jal x1,so
    nop
    j so
    nop


00000000 <so>:
   0:   00000013            nop
   4:   00000013            nop
   8:   00000013            nop
   c:   00000013            nop
  10:   00000013            nop
  14:   00000013            nop
  18:   00000013            nop
  1c:   fe5ff0ef            jal x1,0 <so>
  20:   00000013            nop
  24:   fddff06f            j   0 <so>
  28:   00000013            nop

fe5ff0ef
11111110010111111111000011101111

imm[20|10:1|11|19:12, rd, 110111

1 1111110010 1 11111111 000011101111

1 11111111 1 1111110010 0

0xFFFFFFE4

0x1C + 0xFFFFFFE4 = 0x00000000
实际上是

0xa99ff0ef

10101001100111111111000011101111

imm[20|10:1|11|19:12, rd, 110111

1 0101001100 1 11111111 00001 1101111

1 11111111 1 0101001100

111111111 1010 1001 1000

0xFFFFFA98 + 0x000085e8 = 0x8080
是的,这一切看起来都很好,所以这回到了第一条评论,这是哪个IP?听起来像是未经测试和正在开发

或者,围绕它的代码是这样的,即它没有执行您认为它是的指令

这不是两条压缩指令,下半字的下两位是2b11,这意味着如果代码被半字关闭,则它是一条32位指令 0xfe5f仍然是一条32位指令,但我认为它没有定义

实际上是

0xa99ff0ef

10101001100111111111000011101111

imm[20|10:1|11|19:12, rd, 110111

1 0101001100 1 11111111 00001 1101111

1 11111111 1 0101001100

111111111 1010 1001 1000

0xFFFFFA98 + 0x000085e8 = 0x8080
是的,这一切看起来都很好,所以这回到了第一条评论,这是哪个IP?听起来像是未经测试和正在开发

或者,围绕它的代码是这样的,即它没有执行您认为它是的指令

这不是两条压缩指令,下半字的下两位是2b11,这意味着如果代码被半字关闭,则它是一条32位指令
0xfe5f仍将是一条32位指令,但我认为它尚未定义。

我在RARS中尝试了以下内容,它的工作方式与我们预期的一样

我必须将文本部分移动到RARS的有效范围内,但在其他方面是相同的

    .text 0x00400000
    jal x0, label2     # RARS starts program here

    .text 0x00408080

label1:
    lw  x1, 0(x1)

    .text 0x004085e8
label2:
    jal x1, label1     # <--- here's your instruction
    lw  x2, 0(x2)
这与您的相同(但以小尾端显示,而您以大尾端显示)



看起来您使用的是RV32IMC,因此您使用了压缩指令扩展,使pc可以是2的倍数,而不必是4的倍数。

我在RARS中尝试了以下内容,它的工作方式与我们预期的一样

我必须将文本部分移动到RARS的有效范围内,但在其他方面是相同的

    .text 0x00400000
    jal x0, label2     # RARS starts program here

    .text 0x00408080

label1:
    lw  x1, 0(x1)

    .text 0x004085e8
label2:
    jal x1, label1     # <--- here's your instruction
    lw  x2, 0(x2)
这与您的相同(但以小尾端显示,而您以大尾端显示)



看起来您正在使用RV32IMC,因此您有压缩指令扩展,使pc可以是2的倍数,而不必是4的倍数。

您使用哪种处理器?是自主开发的吗?您使用哪些工具生成程序?再次,自主开发的工具还是来自RISC-V基金会的官员?如果您使用的是自行开发的处理器,但没有使用官方工具,那么您的错误就存在于处理器中。这是github()上的零风险,没有在riscv逻辑中进行自定义。使用GCC开发工具(riscv none GCC)。您使用哪个处理器?是自主开发的吗?您使用哪些工具生成程序?再次,自主开发的工具还是来自RISC-V基金会的官员?如果您使用的是自行开发的处理器,但没有使用官方工具,那么您的错误就存在于处理器中。这是github()上的零风险,没有在riscv逻辑中进行自定义。使用了GCC开发工具(riscv none GCC)。我不明白,“gnu工具被调试”是什么意思?您是如何从
0xeff09fa9
到达
0xa99ff0ef
的?我不明白,“gnu工具已调试”是什么意思?您如何从
0xeff09fa9
到达
0xa99ff0ef