You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么调整arm-none-eabi-ld链接目标文件顺序会改变可执行文件运行行为

问题根本原因
  1. 你通过objcopy将ELF文件转换为了纯二进制bin文件,这类文件不包含任何入口地址、段属性等元信息,只是程序内存镜像的直接拼接。
  2. QEMU的versatilepb平台使用-kernel参数加载bin文件时,会默认将bin内容加载到0x10000地址,直接从0x10000地址开始取指执行,完全不会读取原ELF文件中通过ENTRY(start)指定的入口地址。
  3. 你的链接脚本中.text段的合并规则为*(.text),ld在合并多个目标文件的.text段时,严格按照命令行输入的目标文件顺序排列:
    • 当链接顺序为ts.o t.o时,ts.o的.text段排在最前面,位于0x10000地址的是ts.s中定义的start初始化代码。QEMU启动后会先执行ldr sp, =stack_top设置正确的栈指针,再跳转到main执行,程序运行正常。
    • 当链接顺序为t.o ts.o时,t.o的.text段(即main函数的二进制代码)被排在最前面的0x10000地址。QEMU启动后直接执行main函数的代码,完全没有运行start段的栈初始化逻辑,此时SP还是QEMU上电的默认值(也就是你看到的0xf3575ec0这类不在你规划的内存范围内的地址),后续调用sum函数需要压栈操作时访问非法地址,自然出现异常。
解决方案

你可以选择任意一种方法规避这个问题:

  • 直接使用ELF文件启动QEMU,不需要转换为bin:qemu-system-arm -M versatilepb -kernel t.elf -nographic -serial /dev/null,QEMU会读取ELF头的入口地址执行start代码,不受链接顺序影响。
  • 修改链接脚本的.text段规则,强制将ts.o的代码放在最开头,无论链接顺序如何都能保证入口正确:
.text : { ts.o(.text) *(.text) }

内容的提问来源于stack exchange,提问作者reininger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:24:03