多汇编文件程序的入口点获取及代码执行顺序指定方法
汇编代码排序、Section使用及入口点问题解答
一、用Section强制代码顺序
这是最可靠的方案,具体操作如下:
- 在两个汇编文件中,把需要按顺序排列的代码放到自定义命名的section里,比如:
crt0_generic.s 中:
crt0_customerA.s 中:.section .pre_init.generic, "ax" # "a"表示可分配,"x"表示可执行 generic_pre_init: ; 这里放你要优先执行的指令0-2 ret.section .pre_init.customer, "ax" customer_pre_init: ; 这里放后续执行的指令3-5 ret - 编写或修改链接脚本(.ld文件),指定section的拼接顺序:
链接器会严格按照这个顺序把代码段放到内存里,完全不受编译顺序影响。.pre_init : { *(.pre_init.generic) # 先放generic的section *(.pre_init.customer) # 再放customer的section }
二、其他控制代码顺序的方法
- 调整链接时的文件顺序:用GCC/Clang链接时,先传入crt0_generic.s,再传入crt0_customerA/B.s,链接器会按文件顺序把.text段的代码依次排列。但这种方法依赖命令行的文件顺序,一旦项目文件变多容易出错,不如section方案稳定。
- 显式控制调用顺序:如果不需要强制内存布局,只需要保证函数执行顺序,直接在入口代码里先调用generic的函数,再调用customer的函数就行。比如:
这种方式简单直接,不用改链接脚本。_start: call generic_pre_init call customer_pre_init ; 接着进入C程序的初始化流程 call main
三、让crt0_generic的函数优先被调用
结合上面的方法即可:
- 如果是依赖内存顺序,用section方案保证generic代码在前面,同时在crt0入口点先执行这部分代码;
- 如果只需要执行顺序,直接在汇编入口显式先调用generic的初始化函数,再调用customer的,不管代码在内存里的位置,执行顺序都能保证。
- 要是和C代码配合,也可以给C函数加
__attribute__((constructor(101)))(数字越小优先级越高),但crt0本身是在C运行时之前执行的,所以更建议在汇编入口里控制调用顺序。
四、获取程序的入口点
- 看链接脚本:标准链接脚本里会有
ENTRY(_start)的定义,默认入口是汇编里声明的_start符号;如果自定义了入口,链接脚本里会明确写出来。 - 用工具查看:用
readelf -h 你的可执行文件,输出里的Entry point address就是入口地址;或者用objdump -f 你的可执行文件也能看到入口点信息。 - 自定义入口:如果要修改入口,链接时可以用
-e参数指定,比如gcc -e my_custom_entry ...,或者直接在链接脚本里写ENTRY(my_custom_entry)。
内容的提问来源于stack exchange,提问作者Guillaume D
相关产品推荐
相关产品推荐

