对比参考:剖析.o文件ELF组成

剖析可执行文件ELF组成

相比.o的ELF格式,有哪些变化?

.rel.text和.rel.data消失了

为什么这两个节会消失?

链接器将各.o中同名的.text和.data节整合到一起时,会对整合后的.text和.data进行重定位。其实重定位时主要针对就是.text和.data节,不过这.text和.data节重定位时需要依赖.rel.text和.rel.data中的信息,一旦重定位结束后,这两个节的使命就完成了,自然也就会消失。

多出了两个节

init节

作用

这个节会提供_init等函数,专门用于实现程序的一些初始化。程序入口为_start,从_start开始执行后,在正式调用main函数之前,会先调用_init等函数进行程序的初始化(比如建立函数栈等等)。

init节怎么来的

回顾gcc链接的过程,

 collect2                         //链接程序
  -dynamic-linker  /lib64/ld-linux-x86-64.so.2     //动态链接器
         crt1.o  crti.o  crtbegin.o               //启动代码
         ccyIcm4A.o                      //自己程序的.o
         -lc                                //libc,常用c函数库——c标准库的子库
         crtend.o  crtn.o                   //扫尾代码
 
         init节就是由gcc提供的crt1.o、crti.o、crtbegin.o等.o构建而来的。
“段头部表”节
重定位时,链接器根据“链接脚本文件”所给的运行地址,给.text/.data中指令和变量重定位运行地址时,这些“运行地址”只是链接时理论上安排的。当加载程序到内存中运行时,就需要将硬盘上所存放的程序,搬到“运行地址”所指定的内存位置,段头部表中的内容,就是用来辅助加载程序的。

 

“可执行目标文件”的各个节归类

程序最终运行时,需要搬到内存上的节有:ELF/.init/.text/.rodata/.data/.bss。搬到内存上什么位置呢?搬到重定位的“运行地址”所指定的位置。

ELF/.init/.text/.rodata:只读的存储段(代码段)

.data/.bss:可读可写存储段(静态数据段)。之所以称为静态数据段,是因为.data/.bss的空间规划,是在编译时就进行了理论安排,并不是程序运行起来才安排的,所以被称为静态数据段。

 

程序的加载、运行

编译得到可执行目标文件后,就可以将“可执行目标文件”加载“运行地址”所指的内存位置,然后运行了。不过这里还是要分两种情况来看,第一种是裸机运行的情况,第二种是基于OS虚拟内存运行的情况。

裸机的情况

使用专门针对裸机的编译器来编译程序,最后得到的就是可以在裸机上运行的可执行程序。加载裸机程序时,由专门的加载程序(加载软件)来实现的。

加载

其实加载的过程就是将“代码段”和“数据段”复制到内存上。裸机时,链接器重定位后的“运行地址”是真实的物理地址,加载时直接将“代码段”和“数据段”复制到物理内存中“运行地址”所指定的位置。裸机运行地址是多少,可以由我们程序员自己来定。裸机时就不是ELF格式头了,而是bin格式头。

运行

①CPU的PC(程序计数器)存放第一条指令_start的地址,也就是将PC指向第一条指令_start。pc是cpu的寄存器之一。

②从_start开始执行启动代码。

③启动代码调用_init等函数进行初始化。初始化有一件非常重要的事情就是,从内存划出一片空间出来用作堆和栈,因为空间是以堆和栈的方式来管理的,因此就称为堆 和 栈。

④启动代码调用main函数,main函数再调用各个子函数,我们自己写的代码就开始运行了。

⑤main函数调用return关键字,返回到启动代码。

对于裸机的来说,返回到启动代码就结束了。至于return的返回值,有没有返回值,对于裸机来说都没有什么影响。就算有返回值,将返回值返回给启动代码后,这个返回值对启动代码来说也没有什么意义。所以说,对于裸机来说,其实main函数的返回值没有什么意义,所以大家在学习单片机时候,以前的main函数的返回值都是void的。

void main(void)
{
    return;
}
View Code

相关文章:

  • 2022-12-23
  • 2021-05-22
  • 2021-11-12
  • 2021-11-12
  • 2021-10-19
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-12
  • 2022-01-13
  • 2022-12-23
  • 2021-10-19
相关资源
相似解决方案