elf linux 1
- init段
程序初始化入口代码,在main()之前运行。
- bss段
BSS段属于静态内存分配。通常是指用来存放程序中未初始化的全局变量和未初始化的局部静态变量。未初始化的全局变量和未初始化的局部静态变量默认值是0,本来这些变量也可以放到data
段的,但是因为它们都是0,所以它们在data
段分配空间并且存放数据0是没有必要的。
在程序运行时,才会给BSS段里面的变量分配内存空间。
在目标文件(*.o
)和可执行文件中,BSS段只是为未初始化的全局变量和未初始化的局部静态变量预留位置而已,它并没有内容,所以它不占据空间。
section table中保存了BSS段(未初始化的全局变量和未初始化的局部静态变量)内存空间大小总和。可以通过objdump -h *.o
命令查看到。
- data段
数据段(data segment)通常是指用来存放程序中已初始化的全局变量和已初始化的静态变量的一块内存区域。数据段属于静态内存分配。
- text段
代码段(code segment / text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
- rodata段
存放的是只读数据,比如字符串常量,全局const
变量和#define
定义的常量。本段又称为常量区
。例如:
char *p = "123456";
这里123456
就存放在rodata段中。
但是注意,并不是所有的常量都放在rodata
段的,其特殊情况如下:
1) 有些立即数与指令编译在一起直接放在代码段;
2) 对于字符串常量,编译器会去掉重复的常量,让程序的每个字符串常量只有一份
3) 有些系统中rodata段是多个进程共享的,目的是为了提高空间的利用率
存放未初始化的全局变量,将.data和.bss分开的理由是为了节约磁盘空间,.bss不占实际的磁盘空间---------------------------------------
https://blog.csdn.net/Move_now/article/details/69307890
.bss
不占据实际的磁盘空间,只在段表中记录大小,在符号表中记录符号。当文件加载运行时,才分配空间以及初始化。
VMA和LMA
我们先简要介绍一下VMA
和LMA
这两个字段:
-
VMA
(virtual memory address): 程序区段在执行时期的地址 -
LMA
(load memory address): 某程序区段加载时的地址。因为我们知道程序运行前要经过:编译、链接、装载、运行等过程。装载到哪里呢? 没错,就是LMA对应的地址里。
一般情况下,LMA
和VMA
都是相等的
https://ivanzz1001.github.io/records/post/cplusplus/2018/11/12/cpluscplus-segment