当前位置:网站首页>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程序所依赖的环境。
参考资料
边栏推荐
猜你喜欢
Ubantu专题4:xshell、xftp连接接虚拟机以及设置xshell复制粘贴快捷键
Kubernetes原理剖析与实战应用手册,太全了
How useful is four-quadrant time management?
Internet banking stolen?This article tells you how to use online banking safely
Grafana安装后web打开报错
使用 GraphiQL 可视化 GraphQL 架构
三、数组
DBeaver连接MySQL 8.x时Public Key Retrieval is not allowed 错误解决
第05章 存储引擎【1.MySQL架构篇】【MySQL高级】
Kubernetes common commands
随机推荐
[Meetup Preview] OpenMLDB+OneFlow: Link feature engineering to model training to accelerate machine learning model development
Ubantu project 4: xshell, XFTP connected the virtual machine and set xshell copy and paste the shortcut
Ubantu专题4:xshell、xftp连接接虚拟机以及设置xshell复制粘贴快捷键
mongo enters error
为什么黑客领域几乎一片男生?
工程流体力学复习
Getting Started with TextBlock Control Basic Tools Usage, Get Started
Oracle动态注册非1521端口
多主复制下处理写冲突(4)-多主复制拓扑
做事软件开发-法的重要性所在以及合理结论的认识
TRACE32——常用操作
工程水文学试卷
Kubernetes common commands
Delete table data or clear table
Codeforces Round #796 (Div. 2)(A-D)
Replication Latency Case (3) - Monotonic Read
修改SQL语言实现Mysql 多表关联查询优化
使用 GraphiQL 可视化 GraphQL 架构
Why is the field of hacking almost filled with boys?
Insert into data table to insert data