0

当使用 gnu 工具链,特别是 arm-none-eabi 时,是否有任何理由为什么在使用命令行链接器选项时它会求助于“main”开头的似乎不正确的地址。然而,当'main' 是其他任何东西时,正确的起始地址和堆栈被初始化。例如,

.thumb
.syntax unified

.globl _start
_start:
.word 0x20001000
.word reset

reset:
        bl main
        b .




int main ( void )
{
        return(0);
}


arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <main>:
  8000000:      2000            movs    r0, #0
  8000002:      4770            bx      lr

08000004 <_start>:
  8000004:      20001000        .word   0x20001000
  8000008:      0800000c        .word   0x0800000c

0800000c <reset>:
  800000c:      f7ff fff8       bl      8000000 <main>
  8000010:      e7fe            b.n     8000010 <reset+0x4>

在反汇编中,上面的输出没有从我注意到的正确初始化堆栈0x20001000和启动 rom ,但是..0x08000000

.thumb
.syntax unified

.globl _start
_start:
.word 0x20001000
.word reset

reset:
        bl notmain
        b .




int notmain ( void )
{
        return(0);
}


arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <_start>:
  8000000:      20001000        .word   0x20001000
  8000004:      08000008        .word   0x08000008

08000008 <reset>:
  8000008:      f000 f802       bl      8000010 <xmain>
  800000c:      e7fe            b.n     800000c <reset+0x4>
        ...

08000010 <notmain>:
  8000010:      2000            movs    r0, #0
  8000012:      4770            bx      lr

我尝试通过文件中的工具链查找与链接器脚本有关的任何其他对 main 的引用,并在此过程中获得了一些其他帮助,但似乎没有一个明确的解决方案来解释为什么会这样。当然,如果您创建自己的链接器或生成的链接器,您不会遇到这个问题,但我只是好奇,因为我正在尝试更多地学习该工具。

4

1 回答 1

0

..但我只是好奇,因为我正在尝试更多地学习该工具

arm-eabi-none 旨在与一起使用(作为猜测,因为您没有另外说明)。这可以处理精灵格式的文件,它是一个“库”,但没有操作系统。如果 newlib 机制想main()成为第一,该工具将像这样进行设置。你不想要一个精灵文件,而是一个二进制文件。如果您想要二进制文件(ihex、srec 等),请使用链接描述文件!这就是它的目的。


用于ld --verbose查看默认链接描述文件。您抱怨发出的顺序.text,但您没有做任何事情来定义顺序。可能需要main首先使用链接描述文件,以便其他一些库功能可以工作。您有一个复位向量和一个 CPU,用于初始化堆栈和“复位向量”或初始代码。

这仍然在“坏情况”中发出,但没有正确放置。您需要有一个自定义链接器脚本并将其放在二进制文件中的第一件事。依靠链接器正确放置它很容易出错。工具的升级绝对可以改变顺序。

请参阅:Can _start 是一个拇指函数,如果您有类似的选项,-nostartfiles -static -nostdlib并且使用自定义链接器脚本作为精灵二进制文件不太可能被理解,您需要将二进制文件闪存/刻录到任何引导设备(或内置 CPU)将读取重置向量。

于 2021-01-03T18:20:06.440 回答