链接脚本在编程中的高级运用之一:可变长数组

本文介绍了链接脚本在编程中的高级应用,特别是如何利用链接脚本来实现静态可变长数组。通过分析uboot启动引导模块中的命令模式,展示了如何动态添加命令,避免每次添加新命令都需要修改初始化数组。同时,文章讨论了Linux中类似的技术应用,并强调了链接脚本在内存管理和软件设计中的重要性。
摘要由CSDN通过智能技术生成

作为嵌入式软件工程师,应该要清楚程序的每一条指令在哪里,什么时候会被加载到内存,什么时候会被执行。链接脚本会明确告诉你程序的代码和数据在内存中的分布。精确控制代码和数据在内存中的分布是高效利用内存资源的前提。自定义链接脚本是资深嵌入式软件工程师的必备技能,更是嵌入式架构师的最基本要求。此外,灵活定制链接脚本在编程方面有更高级的应用。


一、编译链接原理

简单讲述编译链接的基本原理有助于后面内容的理解。

a. 简单点说,一个可执行程序包括文件头、代码段(.text)、数据段(.bss)、符号段等信息,在Linux GCC工具链中,该执行程序文件的格式是elf,而在elf格式中,段称为section。现加上某个程序有file1.c和file2.c两个文件。

b. 一个file1.c文件中有代码(函数),也有数据(全局变量,假设都没有初始化的),因此在编译(arm-linux-gcc)之后就会产生一个对应的file1.o,在该文件中会有产生.text section,其会将file.c中所有的函数代码编译后的指令放到该区域,假设长度是0x100字节;同样会产生.bss section,会将所有的全局变量定义到该区域,假设长度是0x20字节。这时,file1.o是可重定位的文件,即.text段是从地址0开始的,其真正的虚拟运行地址还需要在链接阶段重定位完成。

c. 对于另一个file2.c文件,同样会产生对应的file2.o,而该文件中会有对应的.text section(假设长度是0x200字节)和.bss section(假设长度是0x40字节)。其.text段同样是从地址0开始。

d. 链接的最终结果就是产生唯一的一个可执行文件result,而该文件只有一个.text段和一个.bss段,而且.text段会按照指定的链接地址重定位好,即.text段不再是从0开始。那么从这个结果来看,链接的过程应该包括这两个步骤:

d1. 合并file1.o的.text和file2.o的.text到result的.text,其长度为0x100+0x200=0x300字节;合并file1.o的.bss和file2.o的.bss到result的.bss,长度是0x20+0x40=0x60字节

d2. 根据指定的链接地址重定位result的.text段和.bss段,即.text段从指定的地址开始,各个函数的起始地址也会根据该地址进行重新定位。


二、链接脚本基本语法

这里以最基础的链接脚本语法作为示例,GCC工具链下的链接脚本后缀一般是.lds。

ENTRY(_start)//指定_start为程序的第一条指令

SECTIONS//指定内存分布

{

//顿号是地址标识符,这里指定为0x40000000是虚拟运行地址

. = 0x40000000;

//即.text的地址是从0x40000000开始,.text的内容包括file1.o和file2.o的.text

.text :

{

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值