Arm 为什么这个链接器脚本会产生一个地址?
我正在为ARM Cortex-M0微控制器(特别是作为STM32 Discovery开发板一部分的STM32F072B)编写一些固件代码 我的链接器脚本没有任何特殊功能,它只是填充向量表,然后包含代码中的所有文本和数据部分:Arm 为什么这个链接器脚本会产生一个地址?,arm,llvm,stm32,ld,zig,Arm,Llvm,Stm32,Ld,Zig,我正在为ARM Cortex-M0微控制器(特别是作为STM32 Discovery开发板一部分的STM32F072B)编写一些固件代码 我的链接器脚本没有任何特殊功能,它只是填充向量表,然后包含代码中的所有文本和数据部分: OUTPUT_FORMAT("elf32-littlearm") MEMORY { ROM (rx) : ORIGIN = 0x00000000, LENGTH = 16K FLASH (r) : ORIGIN = 0x08000000
OUTPUT_FORMAT("elf32-littlearm")
MEMORY {
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 16K
FLASH (r) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (rw) : ORIGIN = 0x20000000, LENGTH = 16K
}
ENTRY(_start)
PROVIDE(__stack_top = ORIGIN(RAM) + LENGTH(RAM));
SECTIONS {
.vector_table : {
LONG(__stack_top); /* 00 */
LONG(_start); /* 04 */
LONG(dummy_isr); /* 08 */
LONG(dummy_isr); /* 0C */
LONG(dummy_isr); /* 10 */
LONG(dummy_isr); /* 14 */
LONG(dummy_isr); /* 18 */
LONG(dummy_isr); /* 1C */
LONG(dummy_isr); /* 20 */
LONG(dummy_isr); /* 24 */
LONG(dummy_isr); /* 28 */
LONG(dummy_isr); /* 2C */
LONG(dummy_isr); /* 30 */
LONG(dummy_isr); /* 34 */
LONG(dummy_isr); /* 38 */
LONG(dummy_isr); /* 3C */
LONG(dummy_isr); /* 40 */
LONG(dummy_isr); /* 44 */
LONG(dummy_isr); /* 48 */
LONG(dummy_isr); /* 4C */
LONG(dummy_isr); /* 50 */
LONG(dummy_isr); /* 54 */
LONG(dummy_isr); /* 58 */
LONG(dummy_isr); /* 5C */
LONG(dummy_isr); /* 60 */
LONG(dummy_isr); /* 64 */
LONG(dummy_isr); /* 68 */
LONG(dummy_isr); /* 6C */
LONG(dummy_isr); /* 70 */
LONG(dummy_isr); /* 74 */
LONG(dummy_isr); /* 78 */
LONG(dummy_isr); /* 7C */
LONG(dummy_isr); /* 80 */
LONG(dummy_isr); /* 84 */
LONG(dummy_isr); /* 88 */
LONG(dummy_isr); /* 8C */
LONG(dummy_isr); /* 90 */
LONG(dummy_isr); /* 94 */
LONG(dummy_isr); /* 98 */
LONG(dummy_isr); /* 9C */
LONG(dummy_isr); /* A0 */
LONG(dummy_isr); /* A4 */
LONG(dummy_isr); /* A8 */
LONG(dummy_isr); /* AC */
LONG(dummy_isr); /* B0 */
LONG(dummy_isr); /* B4 */
LONG(dummy_isr); /* B8 */
LONG(dummy_isr); /* BC */
} > ROM AT > FLASH
.text : {
*(.text*)
} > ROM AT > FLASH
.rodata : {
*(.rodata*)
*(.data.rel.ro)
} > FLASH
.bss (NOLOAD) : {
*(.bss*)
*(COMMON)
} > RAM
.data : {
*(.data*)
} > RAM
.ARM.exidx : {
*(.ARM.exidx)
} > FLASH
}
当我构建并链接ELF文件并转储符号时,我注意到最后出现在.vector_table
部分的地址以及ELF入口点都被一个关闭:
[shell]$ llvm-objdump --syms zig-cache/bin/main-flash
zig-cache/bin/main-flash: file format elf32-littlearm
SYMBOL TABLE:
00000000 l df *ABS* 00000000 main-flash
0000013c l .text 00000000 $d.1
000000c0 l .text 00000000 $t.0
000000c4 g F .text 00000088 _start
000000c0 g F .text 00000002 dummy_isr
20004000 g *ABS* 00000000 __stack_top
符号表显示0xC4处的\u start
,而链接器脚本中定义为\u start
的ELF入口点设置为0xC5。类似地,写入向量表的dummy_isr
的地址也会被关闭1(dummy_isr
符号定义为0xC0,而0xC1由链接器写入向量表)。对.text
的反汇编确认\u dummy\u isr
和\u start
分别从0xC0和0xC4开始,因此链接器正在写入的地址是错误的:
[shell]$ llvm-objdump --disassemble --section=.text zig-cache/bin/main-flash
zig-cache/bin/main-flash: file format elf32-littlearm
Disassembly of section .text:
000000c0 <dummy_isr>:
c0: fe e7 b #-4 <dummy_isr>
c2: c0 46 mov r8, r8
000000c4 <_start>:
c4: 82 b0 sub sp, #8
c6: 01 23 movs r3, #1
c8: d8 04 lsls r0, r3, #19
ca: 1c 49 ldr r1, [pc, #112]
...
[shell]$llvm objdump--discompose--section=.text zig cache/bin/main flash
zig缓存/bin/main闪存:文件格式elf32 littlearm
第节的分解。正文:
000000c0:
c0:fe e7 b#-4
c2:c0 46 mov r8,r8
000000 C4:
c4:82 b0子sp,#8
c6:01 23 movs r3,#1
c8:d8 04 lsls r0,r3,#19
ca:1c 49 ldr r1,[pc,#112]
...
0xC1和0xC5甚至不是有效指令的地址,它们都在指令的中间。什么会导致这种差异?
这被称为“互通地址” 地址的最低有效位指示目标指令是ARM(0)还是Thumb(1)。获取的地址始终将LSB设置为零 由于此平台仅在Thumb模式下工作,所有矢量地址以及BX和BLX指令使用的地址必须为奇数(X表示(ex)更改指令集)。这称为“互通地址” 地址的最低有效位指示目标指令是ARM(0)还是Thumb(1)。获取的地址始终将LSB设置为零由于此平台仅在Thumb模式下工作,因此所有向量地址以及BX和BLX指令使用的地址必须为奇数(X表示(ex)更改指令集)。请参阅arm文档,向量必须位于处理器地址,或者使用一个。(lsbit设置,表示这是一个thumb函数)如果未设置lsbit,则您将得到一个错误这是否回答了您的问题?“所有其他条目的位[0]必须设置为1,因为该位定义了异常条目上的EPSR.T位。”“在异常条目上,如果相关向量表条目的位[0]为0,则执行第一条指令会导致硬故障。”查看arm文档,向量需要位于处理程序地址或使用一个。(lsbit设置,表示这是一个thumb函数)如果未设置lsbit,则您将得到一个错误这是否回答了您的问题?“所有其他条目的位[0]必须设置为1,因为该位定义了异常条目上的EPSR.T位。”“在异常条目上,如果相关向量表条目的位[0]为0,则执行第一条指令会导致硬故障。”这不是互通,这是异常处理,同样的原因,但bx和blx并没有在本文中使用。我没有说使用bx或blx,我说LSB的目的是相同的。ARM上任何LSB指示目标指令处理器模式的地址都被命名为“互通地址”。这不是互通地址,这是异常处理,原因类似,但在此上下文中不使用bx和blx。我没有说使用bx或blx,我说的是LSB的用途是相同的。ARM上任何LSB指示目标指令处理器模式的地址都称为“互通地址”。
[shell]$ readelf -h zig-cache/bin/main-flash
ELF Header:
...
Entry point address: 0xc5
[shell]$ llvm-objdump --disassemble --section=.text zig-cache/bin/main-flash
zig-cache/bin/main-flash: file format elf32-littlearm
Disassembly of section .text:
000000c0 <dummy_isr>:
c0: fe e7 b #-4 <dummy_isr>
c2: c0 46 mov r8, r8
000000c4 <_start>:
c4: 82 b0 sub sp, #8
c6: 01 23 movs r3, #1
c8: d8 04 lsls r0, r3, #19
ca: 1c 49 ldr r1, [pc, #112]
...