欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 【ARM/RISCV 嵌入式 编译系列 16 -- GCC 进制优化编译的常用方法】

【ARM/RISCV 嵌入式 编译系列 16 -- GCC 进制优化编译的常用方法】

2025/5/29 5:00:34 来源:https://blog.csdn.net/sinat_32960911/article/details/148176783  浏览:    关键词:【ARM/RISCV 嵌入式 编译系列 16 -- GCC 进制优化编译的常用方法】

文章目录

      • 方法一:给函数加 __attribute__((used)) 强制保留
      • 方法二:加 __attribute__((section(".text.jump"))) + 链接脚本强制放入
      • 方法三:关闭函数优化和链接时清除未使用代码
    • 如果是纯汇编写的(`.S`)
    • 最强一招:使用 `KEEP()` 保留段内所有代码
    • 验证跳转函数是否真的保留
    • 总结

方法一:给函数加 attribute((used)) 强制保留

如果你是用 C 写的(而不是纯汇编),这样做可以让函数即使没被调用也不被优化掉:

__attribute__((used))
void jump_to_ilm() {asm volatile ("lui t0, 0x60000\n""jr t0\n");
}

方法二:加 attribute((section(“.text.jump”))) + 链接脚本强制放入

__attribute__((used, section(".text.jump")))
void jump_to_ilm() {asm volatile ("lui t0, 0x60000\n""jr t0\n");
}

并在链接脚本中加入:

.text : {KEEP(*(.text.jump))*(.text)
}

方法三:关闭函数优化和链接时清除未使用代码

在编译时使用以下选项:

riscv64-elf-gcc -O0 -Wl,--whole-archive -Wl,--no-gc-sections ...

或者最少加 -Wl,--gc-sections 时配合 KEEP() 保住关键段落。

如果是纯汇编写的(.S

确保该跳转代码出现在 _start 或其他被链接器引用的地方,否则链接器仍可能把你 .text 中的符号扔掉。

例如:

.section .text
.globl _start
_start:lui t0, 0x60000jr t0

_start 是入口符号,必须通过链接脚本 ENTRY(_start) 指定入口,否则编译器也可能不处理。

最强一招:使用 KEEP() 保留段内所有代码

在链接脚本中:

.text : {KEEP(*(.text.boot))KEEP(*(.text.jump))*(.text*)
}

只要你把函数放进 .text.jump,它就不会被优化掉了。

验证跳转函数是否真的保留

你可以用 objdump 检查 ELF 文件:

riscv64-elf-objdump -d bootrom.elf | less

确认是否有类似:

60000000 <_ilm_main>:...

总结

方法适用情况是否推荐
__attribute__((used))写在 C 代码中推荐
KEEP() + section写在链接脚本 + C/汇编都适用强力推荐
直接放在 _start简单项目推荐
关闭优化(-O0, --no-gc-sections调试期可用有副作用,慎用

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词