当使用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
和rom0x08000000
的启动,但是。。
.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的任何其他引用,并在这一过程中获得了一些其他帮助,但似乎没有一个明确的解决方案来解释为什么会这样。当然,如果你创建了自己的链接器或生成的链接器,你就不会遇到这个问题,但我只是很好奇,因为我正在尝试更多地学习这个工具。
。。但我只是好奇,因为我正试图学习更多的工具
arm eabi none旨在与newlib一起使用(作为猜测,因为您没有另行说明(。这可以处理elf格式的文件,它是一个"库",但没有操作系统。如果newlib机制希望main()
是第一个,那么该工具将设置如下。您不想要一个elf文件,而是一个二进制文件。如果您想要一个二进制文件(ihex、srec等(,请使用链接器脚本!这就是它的意义所在。
使用ld --verbose
查看默认链接器脚本。您在抱怨已发出的.text
的顺序,但您没有对顺序进行任何定义。链接器脚本可能需要首先使用main
,以便其他库功能可以工作。您有一个重置向量和一个初始化堆栈和"重置向量"或初始代码的CPU。
这仍然是在"坏情况"下发出的,但没有正确放置。您需要有一个自定义链接器脚本,并将其定位为二进制文件中的第一件事。依赖链接器来正确放置它是容易出错的。工具的升级肯定会改变顺序。
请参阅:如果您有-nostartfiles -static -nostdlib
之类的选项,并使用自定义链接器脚本作为elf二进制文件,则_start可以是一个拇指函数。这不太可能被理解,您需要将二进制文件闪存/刻录到要读取重置矢量的任何引导设备(或内置CPU(。