【问题标题】:RiscV jumps (j, jal) to wrong address (off by offset 2)RiscV 跳转 (j, jal) 到错误的地址(偏移量 2)
【发布时间】:2019-04-09 09:30:35
【问题描述】:

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

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

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

但是,在执行跳转指令后发生的情况是,我降落在地址 0x00008082 而不是预期的 0x00008080。

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

【问题讨论】:

  • 您使用哪种处理器?是自己开发的吗?您使用哪些工具生成程序?再说一遍,是自研工具还是来自 RISC-V 基金会的官员?如果您使用的是自行开发的处理器但官方工具,那么您的错误就在您的处理器中。
  • 这是在 github (github.com/pulp-platform/zero-riscy) 上找到的零风险,没有在 riscv 逻辑中进行自定义。使用 GCC 开发工具 (riscv-none-gcc)。

标签: assembly riscv


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    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 位指令,但我认为它是未定义的。

    【讨论】:

    • 我没听懂,'gnu tools are debugged' 是什么意思?你如何从0xeff09fa9 到达0xa99ff0ef
    【解决方案3】:

    我在 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 的倍数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-27
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      相关资源
      最近更新 更多