«auipc dest, label» (и «la dest, label») не дают ожидаемого листинга - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь написать ассемблерный код для RISC-V (впервые для RISC-V, хотя Я написал для нескольких других процессоров) и то, что я вижу в списке, не выглядит что я ожидал: я пытаюсь использовать "la dest, label" для загрузки адреса метки в регистр, который позже будет использоваться в качестве указателя. Однако в В листинге я вижу значения ПК-относительных смещений в виде нулей. Когда я вставляю инструкцию "j label" просто для проверки ассемблера, я вижу поля смещения команд правильных значений. Как будто "auipc" инструкция не работает правильно (или я делаю ошибку для некоторых новичков).

Я использую ассемблер "binutils-2.28", скомпилированный для цели "Riscv32".

Вот код ассемблера:

.section .text
.globl _start
_start:


.equ    MON_OUT_ADDR,                   0x00000000      #       TBD
.equ    MON_BASE_ADDR,                  0x12345678      #       TBD

.equ    MON_OUT_ADDR_OFFSET,                    0x0
.equ    BASE_ADDR_OFFSET,                               0x4



#.org 0x0                                                                               #       TBD.
mon_isr:

        j       isr_data                                                #       <=== Dummy instruction, just to test riscv32-as
        la              x1,isr_data                                     #       x1 - ISR data ptr.

        la              x1,wfi_endless_loop                     #       <=== Dummy instruction, just to test riscv32-as
        lui             x1,%hi(isr_data)                        #       <=== Dummy instruction, just to test riscv32-as
        auipc   x1,%pcrel_hi(isr_data)          #       <=== Dummy instruction, just to test riscv32-as
        addi    x1,x1,%lo(isr_data)                     #       <=== Dummy instruction, just to test riscv32-as
        auipc   x1,%hi(0x00010004)                      #       <=== Dummy instruction, just to test riscv32-as
        addi    x1,x1,%lo(0x00010004)           #       <=== Dummy instruction, just to test riscv32-as

        lw              x15,MON_OUT_ADDR_OFFSET(x1)
        lw              x8,BASE_ADDR_OFFSET(x1)

wfi_endless_loop:
        j               wfi_endless_loop





.org    0x00010000


#isr_data:
.word   MON_OUT_ADDR

isr_data:
.word   MON_BASE_ADDR

А вот и список:

GAS LISTING /some_path/temp/riscv_asm/debug.asm                         page 1


   1                    .section .text
   2                    .globl _start
   3                    _start:
   4
   5
   6                    .equ    MON_OUT_ADDR,                   0x00000000      #       TBD
   7                    .equ    MON_BASE_ADDR,                  0x12345678      #       TBD
   8
   9                    .equ    MON_OUT_ADDR_OFFSET,                    0x0
  10                    .equ    BASE_ADDR_OFFSET,                               0x4
  11
  12
  13
  14                    #.org 0x0                                                                               #      TBD.
  15                    mon_isr:
  16
  17 0000 6F004100              j       isr_data                                                #       <=== Dummy instruction, just to test riscv32-as
  18 0004 97000000              la              x1,isr_data                                     #       x1 - ISR data ptr.
  18      93800000
  19
  20 000c 97000000              la              x1,wfi_endless_loop                     #       <=== Dummy instruction, just to test riscv32-as
  20      93800000
  21 0014 B7000000              lui             x1,%hi(isr_data)                        #       <=== Dummy instruction, just to test riscv32-as
  22 0018 97000000              auipc   x1,%pcrel_hi(isr_data)          #       <=== Dummy instruction, just to test riscv32-as
  23 001c 93800000              addi    x1,x1,%lo(isr_data)                     #       <=== Dummy instruction, just to test riscv32-as
  24 0020 97000100              auipc   x1,%hi(0x00010004)                      #       <=== Dummy instruction, just to test riscv32-as
  25 0024 93804000              addi    x1,x1,%lo(0x00010004)           #       <=== Dummy instruction, just to test riscv32-as
  26
  27 0028 83A70000              lw              x15,MON_OUT_ADDR_OFFSET(x1)
  28 002c 03A44000              lw              x8,BASE_ADDR_OFFSET(x1)
  29
  30                    wfi_endless_loop:
  31 0030 6F000000              j               wfi_endless_loop
  32
  33
  34
  35
  36
  37 0034 00000000      .org    0x00010000
  37      00000000
  37      00000000
  37      00000000
  37      00000000
  38
  39
  40                    #isr_data:
  41 10000 00000000     .word   MON_OUT_ADDR
  42
  43                    isr_data:
  44 10004 78563412     .word   MON_BASE_ADDR
  45
  46

GAS LISTING /some_path/temp/riscv_asm/debug.asm                         page 2


DEFINED SYMBOLS
/some_path/temp/riscv_asm/debug.asm:3      .text:0000000000000000 _start
/some_path/temp/riscv_asm/debug.asm:6      *ABS*:0000000000000000 MON_OUT_ADDR
/some_path/temp/riscv_asm/debug.asm:7      *ABS*:0000000012345678 MON_BASE_ADDR
/some_path/temp/riscv_asm/debug.asm:9      *ABS*:0000000000000000 MON_OUT_ADDR_OFFSET
/some_path/temp/riscv_asm/debug.asm:10     *ABS*:0000000000000004 BASE_ADDR_OFFSET
/some_path/temp/riscv_asm/debug.asm:15     .text:0000000000000000 mon_isr
/some_path/temp/riscv_asm/debug.asm:43     .text:0000000000010004 isr_data
/some_path/temp/riscv_asm/debug.asm:30     .text:0000000000000030 wfi_endless_loop
/some_path/temp/riscv_asm/debug.asm:18     .text:0000000000000004 .L0
/some_path/temp/riscv_asm/debug.asm:20     .text:000000000000000c .L0

NO UNDEFINED SYMBOLS

Смещение в инструкциях типа "la x1, isr_data" выглядит как ноль в то время как должна быть разница между адресом этой метки (0x10004) и адрес следующей инструкции, IIRC. В ассемблере есть ошибка или я что-то не так делаю?

ТИА!

1 Ответ

1 голос
/ 05 апреля 2019

Я подозреваю, что причина непосредственных полей равна 0, потому что вы смотрите на объектный файл, который не был связан.

если вы запустите readelf на своем исполняемом файле с -r, который показывает информацию о перемещении, вы должны увидеть что-то вроде:

Relocation section '.rela.text' at offset 0x1018c contains 11 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000004  00000917 R_RISCV_PCREL_HI2 00010004   isr_data + 0
00000008  00000b18 R_RISCV_PCREL_LO1 00000004   .L0  + 0
0000000c  00000a17 R_RISCV_PCREL_HI2 00000030   wfi_endless_loop + 0
00000010  00000c18 R_RISCV_PCREL_LO1 0000000c   .L0  + 0
00000014  0000091a R_RISCV_HI20      00010004   isr_data + 0
00000014  00000033 R_RISCV_RELAX                0
00000018  00000917 R_RISCV_PCREL_HI2 00010004   isr_data + 0
0000001c  0000091b R_RISCV_LO12_I    00010004   isr_data + 0
0000001c  00000033 R_RISCV_RELAX                0
00000000  00000911 R_RISCV_JAL       00010004   isr_data + 0
00000030  00000a11 R_RISCV_JAL       00000030   wfi_endless_loop + 0

Это информация, которую компоновщик будет использовать для замены значенийв инструкции с их правильными значениями и сделать программу исполняемой.Таким образом, причина, по которой непосредственные значения всегда равны 0, заключается в том, что им еще не было дано окончательное значение.

Вы можете сделать исполняемый объектный файл, выполнив riscv-ld yourobject.o -o yourexecutable

...