RiscV跳转(j,jal)到错误的地址(偏移量为2)

时间:2019-04-09 09:30:36

标签: assembly riscv risc

我正在使用riscV处理器(RV32)。通过我编写的一些代码,我注意到了一些奇怪的事情。当我使用“ JAL”指令或“ J”指令跳转到特定地址时,似乎偏移量计算不正确。

假设我要跳转到地址0x00008080上有一些代码(PRAM_ResetVector)。

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

但是,执行跳转指令后发生的是我到达了地址0x00008082而不是原来的0x00008080。

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

3 个答案:

答案 0 :(得分:1)

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

gnu工具已调试,因此

0xeff09fa9

实际上是

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位指令,但我认为它是未定义的。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我在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)

该分支起作用,并将控制权转移给label1。

RARS汇编注释的指令并将机器代码字报告为:

a99ff0ef

与您的相同(但以小尾数显示,而以大尾数显示)。


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