当前位置:网站首页>C程序是如何跑起来的01 —— 普通可执行文件的构成
C程序是如何跑起来的01 —— 普通可执行文件的构成
2022-07-31 15:37:00 【Mculover666】
学习目的
- 程序烧到什么地方?
- 程序加载到内存什么地方?
- 程序如何执行?
一、编译环境搭建
ubuntu 20.04使用arm-linux-gnueabihf-gcc 7.5.0。
二、程序源码
main.c:
#include <stdio.h>
#include "calc.h"
int main(int argc, char *argv[])
{
int a, b;
static int local_val = 2;
static int uninit_local_val;
a = add(2, 3);
b = sub(5, 4);
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
calc.h:
#ifndef _CALC_H_
#define _CALC_H_
int add(int a, int b);
int sub(int a, int b);
#endif
calc.c:
#include "calc.h"
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
编译:
arm-linux-gnueabihf-gcc main.c calc.c
交叉编译生成 a.out 可执行文件,文件类型是32位ARM平台可执行文件。
三、readelf工具
readelf工具由编译器提供,用来列出关于可执行文件的内容的相关信息。
使用格式如下:
Usage: readelf <option(s)> elf-file(s)
(1)查看可执行文件的头部 信息
-h:用于列出ELF文件的头部信息,包括可执行文件运行的平台、软件版本、程序入口地址,以及program headers、section header等信息;

(2)查看section header
-S:用于列出程序中section的头部信息

四、可执行文件的组成结构
一个可执行文件由一系列section构成,section称为段,包括:代码段text、只读数据段rodata、数据段data、bss段等。

每个section用一个section header描述,包括段名、段的类型、段的起始地址、段的偏移、段的大小等。
将可执行文件的所有section header集合到一起就是section header table,使用readelf 的 -S 参数查看的就是该表。
在程序编译的时候,对C语言代码中定义的函数、变量、未初始化的全局变量进行编译分类,放置在不同的段中:
- 普通代码翻译成二进制放到代码段(text)中
- 常量放在只读数据段(rodata)中
- 初始化的全局变量和静态局部变量放在数据段(data)中
BSS段比较特殊,未初始化的全局变量和静态变量都会放置到bss段中,但因为这些变量的值都是0,没有必要再开辟空间存储,所以在可执行文件中bss段是不占用空间的。
但是BSS段的大小、起始地址、各个变量的地址信息都会分别保存在section header table和符号表symtab中,当程序运行的时候,加载器会根据这些信息在内存中紧挨着数据段之后的空间,为BSS段开辟一片存储空间,为各个变量分配存储空间。
总而言之:BSS段在可执行文件中不占用空间,在程序运行的时候才分配对应的空间。
如果在编译时开启了调试选项,则可执行文件中还会有 .debug section,用来保存可执行文件中每一条二进制指令对应的源码位置信息,根据这些信息,GDB调试器就可以支持源码级的单步调试。
在最后环节,编译器还会在可执行文件中添加一些其它的section,比如 .init section,这些代码来自C语言运行库的一些汇编代码,用来初始化C程序所依赖的环境。

参考资料
边栏推荐
猜你喜欢

Synchronized and volatile interview brief summary

TRACE32 - Common Operations

leetcode303场周赛复盘
![[Meetup Preview] OpenMLDB+OneFlow: Link feature engineering to model training to accelerate machine learning model development](/img/f6/311d5a4c70993df6291250d2025d3f.jpg)
[Meetup Preview] OpenMLDB+OneFlow: Link feature engineering to model training to accelerate machine learning model development

"Autumn Recruitment Series" MySQL Interview Core 25 Questions (with answers)

长得很怪的箱图

mongo enters error

Efficient use of RecyclerView Section 1

女性服务社群产品设计

t-sne 数据可视化网络中的部分参数+
随机推荐
mysql黑窗口~建库建表
OPPO在FaaS领域的探索与思考
Public Key Retrieval is not allowed error solution when DBeaver connects to MySQL 8.x
The new BMW 3 Series is on the market, with safety and comfort
MySQL数据库操作
定时器的类型
贪吃蛇项目(简单)
第二届中国PWA开发者日
Snake Project (Simple)
[Meetup Preview] OpenMLDB+OneFlow: Link feature engineering to model training to accelerate machine learning model development
WPF project - basic usage of controls entry, you must know XAML
type of timer
TRACE32——基于SNOOPer的变量记录
Qt实战案例(54)——利用QPixmap设计图片透明度
Unity中实现点选RenderTexture中的3D模型
Gorm—Go language database framework
为什么毕业季不要表白?
The use of border controls
做事软件开发-法的重要性所在以及合理结论的认识
腾讯云部署----DevOps