博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数
阅读量:1997 次
发布时间:2019-04-28

本文共 1148 字,大约阅读时间需要 3 分钟。

上一篇文章,大概了解了链接器的工作内容就是:符号解析和重定位。点击上一篇文章查看:。

本片文章其实还是围绕链接器来学习。只不过不是很明显,当你学到下一篇文章时,就明白了。

本篇文章来弄明白一个问题:在C/C++程序被加载到内存中准备运行时,main函数是第一个被执行的函数么?答案肯定不是!如果是,就没必要去写这个文章了!!!

1、_start()函数

先说结果:_start() 是第一个被执行的函数,而不是main()函数。

我们的程序中并没有写_start() ,它是通过链接器链接到可执行文件中的(下一篇文章可以学习到这是如何办到的)。

在默认情况下(gcc)

  • 程序加载后,_start()是第一个被执行的函数
  • _start()函数,准备好参数后,立即调用 __libc_start_main() 函数
  • __libc_start_main() 初始化运行环境后,调用main()函数执行

注意:_start()函数的入口地址就是代码段(.text)的起始地址

2、__libc_start_main()函数的作用

__lib_start_main()函数的作用

  • 调用__libc_csu_init()函数(完成必要的初始化操作)
  • 启动程序的第一个线程(主线程),main()函数为主线程入口
  • 注册__libc_csu_fini()函数(程序运行终止时被调用)

3、程序的启动过程

下面给一个简图,来说明一个C/C++程序的执行过程:

在这里插入图片描述

4、自定义程序的入口函数

  • gcc 提供-e选项,用于在链接时指定入口函数
  • 自定义入口函数时,必须使用选项 -nostartfiles 进行链接

比如以下程序:

program.c

#include 
#include
int program(){
printf("D.T.Software\n"); exit(0);}

很明显它没有main函数。但是我们通过以下编译命令进行编译:

  • gcc -e program -nostartfiles program.c -o program

生成可执行文件 program

运行该可执行文件: ./program

可以得到运行结果:

在这里插入图片描述

显而易见,我们改变了程序的入口函数。虽然没有写main函数,但是依然可以运行该程序!!!

5、总结

本文主要是理解程序的入口函数。最好自己私底下做实验,看一下可执行文件的反汇编代码,就知道整个程序的执行流程了。

本文参考狄泰软件学院相关课程

想学习的可以加狄泰软件学院群,
群聊号码:199546072

学习探讨加个人(可以免费帮忙下载CSDN资源):

qq:1126137994
微信:liu1126137994

转载地址:http://pbytf.baihongyu.com/

你可能感兴趣的文章
Spring Cloud Consul应用下线后,健康检查自动删除无效服务
查看>>
spring cloud consul 应用的多实例名的解决
查看>>
kafka设置某个topic的数据过期时间
查看>>
linux系统编程之信号(五):实时信号与sigqueue函数
查看>>
225. 用队列实现栈
查看>>
linux系统编程之信号(六):竞态条件与sigsuspend函数
查看>>
124. 二叉树中的最大路径和
查看>>
LeetCode 148:排序链表 【归并】
查看>>
LeetCode 560 和为 k 的子数组
查看>>
LeetCode 581 最短无序连续子数组
查看>>
Flink本地部署报错 Could not resolve ResourceManager address ,提交job,显示taskmanagers等均为0
查看>>
Java Stream 使用
查看>>
Flink 的DataStream 和 DataSet区别
查看>>
Flink源码学习
查看>>
MYSQL 表的手动更新统计分析记录
查看>>
MYSQL的身体,POSTGRESQL 的头脑
查看>>
PostgreSQL 高可用Patroni和学习方法
查看>>
业务卡单 与 MongoDB性能记录与分析
查看>>
MYSQL 中的查询技巧 与 MYSQL 8 并行查询
查看>>
MYSQL 8 Serialized Dictionary Information
查看>>