assembly - “auipc dest, label”(和“la dest,label”)不会产生预期的列表
问题描述
我正在尝试为 RISC-V 编写汇编程序代码(第一次为 RISC-V 编写,尽管我为其他几个 CPU 编写过),而我在清单中看到的内容与我的预期不同:我正在尝试使用"la dest,label" 将标签的地址加载到稍后将用作指针的寄存器中。但是,在清单中,我将 PC 相对偏移的值视为零。当我插入“j 标签”指令只是为了测试汇编程序时,我看到了正确值的指令偏移字段。好像“auipc”指令不能正常工作(或者我犯了一些初学者的错误)。
我正在使用为“riscv32”目标编译的“binutils-2.28”汇编程序。
这是汇编代码:
.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 之间的差异。汇编器中有错误还是我做错了什么?
蒂亚!
解决方案
我怀疑直接字段为 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
推荐阅读
- javascript - Angular 7 - 没有用于具有未指定名称属性的表单控件的值访问器
- python - Python继承:修改对象的父类
- javascript - 如何将自定义类型转换为原始类型?
- python - 来自 gcs 的 Bigquery 命令行 'bq load' 失败。Traceback 显示 google-cloud-sdk 的引导模块中缺少“ReadFileContents”属性
- c - RegExp 在其他单词中间时不匹配
- entity-framework - 在 Entity Framework Core 2.0 中替换服务的正确方法
- jquery - 单击 jquery 时的下拉菜单 CSS
- r - ngram 参考 quanteda 中的 docname
- regex - and-or-lists(或and-or-trees)的数据结构的名称是什么,我在哪里可以阅读它?
- git - 如何使用 Azure CI CD 进程将 GitHub 存储库的多个文件夹同步到单个 AzureGit