RiscV переходит (j, jal) к неправильному адресу (отключено по смещению 2) - PullRequest
0 голосов
/ 09 апреля 2019

Я использую процессор riscV (RV32).С некоторым кодом, который я написал, я заметил кое-что странное.Когда я использую инструкцию «JAL» или «J» для перехода к определенному адресу, создается впечатление, что смещение не рассчитывается правильно.

Допустим, у меня есть некоторый код (PRAM_ResetVector), расположенный по адресу0x00008080 Я хочу перейти к.

Код перехода выглядит следующим образом в сборке "jal x1, PRAM_ResetVector" и расположен по адресу 0x000085e8.Кодировка инструкции (risc32) выглядит следующим образом: 0xeff09fa9.

Однако после выполнения команды перехода происходит то, что я приземляюсь по адресу 0x00008082 вместо предполагаемого 0x00008080.

Мне кажется, что я не могунайти причину этого, кто-нибудь может помочь здесь?

Ответы [ 3 ]

1 голос
/ 10 апреля 2019
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-битной инструкцией, ноЯ думаю, что это не определено.

0 голосов
/ 11 апреля 2019

Я попробовал следующее в 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, поэтому у вас есть расширение сжатых инструкций, которое позволяет компьютеру быть кратным 2, не обязательно кратным 4.

0 голосов
/ 10 апреля 2019

Инструкция "0xeff09fa9"? Эти 32-битные на самом деле две разные двухбайтовые инструкции, c.sd и c.addw.

...