文章目录
如何写链接脚本
两个概念
链接地址:链接的时候指定的地址
运行地址:程序实际运行时候的地址
背景知识
在明白如何写链接脚本之前需要明白几个概念:当.s和.c源文件经过编译器编译后生成.o目标文件的时候,在目标
文件(二进制文件)中数据是以一段段的二进制分块存储的。主要包含以下几种:
代码段(.text):源文件函数部分编译得到的片段
数据段(.data):C语言显式初始化为非零的全局变量编译得到的片段
bss段(zi段)(.bss):C语言经显式初始化为零的全局变量得到的片段
自定义段:自定义的片段
链接脚本的书写规范
整个脚本代码需要用一个SECTIONS{}括起来;以下为括号里面的内容:
1. 第一行定义链接地址的起始地址,例如:. = 0x20000000;
2.各段的位置按代码的前后位置摆放:如
.text : {
start.0
*(.text)
}
.data : {
*(.data)
}
此脚本链接后的可执行文件中,start.o中的代码段会放在其他代码段之前的地址中,代码段会放在数据段之前的位置
3.赋值语句的代码段后面要加分号(;)
4.一个栗子:
SECTIONS
{
. = 0X20000000;
.text :{
start.o
*(.text)
}
.data{
*(.data)
}
bss_start = . ;
.bss :
{
*(.bss)
}
bss_end= .;
}
如何实现重定位
什么是重定位?
重定位,就是将一些代码从当前运行的位置,copy到链接指向的地址;
为什么要重定位
由于一些不得已的原因,程序下载的地址并不是链接指向的地址,那么cpu在运行一些位置相关码的时候就会出错(
比如调用一个函数)使用 ldr pc, _MAIN这个时候,pc指针指向的_MAIN表示的地址并不是实际main函数的入口地址&