LINUX下目标文件的BSS段、数据段、代码段
http://blog.chinaunix.net/uid-27018250-id-3867588.html
bss 未初始化的全局数据
data 已经初始化的全局数据
text 代码段,机器指令
rodata 字符串常量
参考:《程序员自我修养》
代码编译后的机器指令经常被放在代码段里,代码段名为".text";已初始化的全局变量和已初始化的局部静态变量经常放在数据段里,数据段名为".data";未初始化的全局变量和未初始化局部静态变量一般放在“.bss”段里,.bss在文件中不占据空间。字符串常量一般放在“.rodata”段里。
通过代码编译后查看文件内部结构来论证一下上面观点,代码如下:
代码:
点击(此处)折叠或打开
- int printf(const char* format, ...);
- int global_init_var = 84; //已初始化的全局变量
- int global_uninit_var; //未初始化的全局变量
- char *str1 = "hello world!"; //字符串常量
- void func1(int i)
- {
- printf("%d\n", i);
- }
- int main(void)
- {
- static int static_var = 85; //已初始化的静态局部变量
- static int static_var2; //未初始化的静态局部变量
- char *str2 = "22222"; //字符串常量
- int a = 1;
- int b;
- func1(static_var+static_var2+a+b);
- return a;
- }
上面代码保存为1.c,编译生成目标文件1.o:
点击(此处)折叠或打开
- gcc -c 1.c
使用objdump来查看目标文件的结构和内容,命令如下:
点击(此处)折叠或打开
- objdump -s -d 1.o
目标文件结构和内容如下(只保留.bss段、.text段、.data段、.rodata段):
点击(此处)折叠或打开
- 1.o: file format elf32-i386
- Contents of section .text:
- 0000 5589e583 ec188b45 08894424 04c70424 U......E..D$...$
- 0010 0d000000 e8fcffff ffc9c355 89e583e4 ...........U....
- 0020 f083ec20 c7442414 11000000 c7442418 ... .D$......D$.
- 0030 01000000 8b150800 0000a100 00000001 ................
- 0040 c28b4424 1801c28b 44241c01 d0890424 ..D$....D$.....$
- 0050 e8fcffff ff8b4424 18c9c3 ......D$...
- Contents of section .data:
- 0000 54000000 00000000 55000000 T.......U...
- Contents of section .rodata:
- 0000 68656c6c 6f20776f 726c6421 0025640a hello world!.%d.
- 0010 00323232 323200 .22222.
- Disassembly of section .text:
- 00000000 <func1>:
- 0: 55 push %ebp
- 1: 89 e5 mov %esp,%ebp
- 3: 83 ec 18 sub $0x18,%esp
- 6: 8b 45 08 mov 0x8(%ebp),%eax
- 9: 89 44 24 04 mov %eax,0x4(%esp)
- d: c7 04 24 0d 00 00 00 movl $0xd,(%esp)
- 14: e8 fc ff ff ff call 15 <func1+0x15>
- 19: c9 leave
- 1a: c3 ret
- 0000001b <main>:
- 1b: 55 push %ebp
- 1c: 89 e5 mov %esp,%ebp
- 1e: 83 e4 f0 and $0xfffffff0,%esp
- 21: 83 ec 20 sub $0x20,%esp
- 24: c7 44 24 14 11 00 00 movl $0x11,0x14(%esp)
- 2b: 00
- 2c: c7 44 24 18 01 00 00 movl $0x1,0x18(%esp)
- 33: 00
- 34: 8b 15 08 00 00 00 mov 0x8,%edx
- 3a: a1 00 00 00 00 mov 0x0,%eax
- 3f: 01 c2 add %eax,%edx
- 41: 8b 44 24 18 mov 0x18(%esp),%eax
- 45: 01 c2 add %eax,%edx
- 47: 8b 44 24 1c mov 0x1c(%esp),%eax
- 4b: 01 d0 add %edx,%eax
- 4d: 89 04 24 mov %eax,(%esp)
- 50: e8 fc ff ff ff call 51 <main+0x36>
- 55: 8b 44 24 18 mov 0x18(%esp),%eax
- 59: c9 leave
- 5a: c3 ret
我们先来看一下.data段里数据:
点击(此处)折叠或打开
- Contents of section .data:
- 0000 54000000 00000000 55000000 T.......U...
因为已初始化的全局变量和已初始化的局部静态变量经常放在.data段里,因为偶的CPUX86是小端,低字节放低位,54000000转化十进制为84,55000000转化为十进制为85,刚好对应代码中的global_init_var = 84和static_var = 85。
然后我们来看一下.rodata段的数据:
点击(此处)折叠或打开
- Contents of section .rodata:
- 0000 68656c6c 6f20776f 726c6421 0025640a hello world!.%d.
- 0010 00323232 323200 .22222.
.rodata里面你可以看到有个数据,分别为“hello world!”、“%d\n”、"22222",这三个数据分别对应了代码中的三个字符串常量。所以字符串常量一般放在“.rodata”段里。
接下来就是代码段.text:
点击(此处)折叠或打开
- Contents of section .text:
- 0000 5589e583 ec188b45 08894424 04c70424 U......E..D$...$
- 0010 0d000000 e8fcffff ffc9c355 89e583e4 ...........U....
- 0020 f083ec20 c7442414 11000000 c7442418 ... .D$......D$.
- 0030 01000000 8b150800 0000a100 00000001 ................
- 0040 c28b4424 1801c28b 44241c01 d0890424 ..D$....D$.....$
- 0050 e8fcffff ff8b4424 18c9c3 ......D$...
看到.text段中的两个以"55 89 e5 83 ec ec 18 8b 45"和"89 e5 83 e4 f0 83 ec 20"开头的数据。分别对应汇编代码编译以后的机器指令(十六进制数据相同),见如下:
点击(此处)折叠或打开
- Disassembly of section .text:
- 00000000 <func1>:
- 0: 55 push %ebp
- 1: 89 e5 mov %esp,%ebp
- 3: 83 ec 18 sub $0x18,%esp
- 6: 8b 45 08 mov 0x8(%ebp),%eax
- 9: 89 44 24 04 mov %eax,0x4(%esp)
- d: c7 04 24 0d 00 00 00 movl $0xd,(%esp)
- 14: e8 fc ff ff ff call 15 <func1+0x15>
- 19: c9 leave
- 1a: c3 ret
- 0000001b <main>:
- 1b: 55 push %ebp
- 1c: 89 e5 mov %esp,%ebp
- 1e: 83 e4 f0 and $0xfffffff0,%esp
- 21: 83 ec 20 sub $0x20,%esp
- 24: c7 44 24 14 11 00 00 movl $0x11,0x14(%esp)
- 2b: 00
- 2c: c7 44 24 18 01 00 00 movl $0x1,0x18(%esp)
- 33: 00
- 34: 8b 15 08 00 00 00 mov 0x8,%edx
- 3a: a1 00 00 00 00 mov 0x0,%eax
- 3f: 01 c2 add %eax,%edx
- 41: 8b 44 24 18 mov 0x18(%esp),%eax
- 45: 01 c2 add %eax,%edx
- 47: 8b 44 24 1c mov 0x1c(%esp),%eax
- 4b: 01 d0 add %edx,%eax
- 4d: 89 04 24 mov %eax,(%esp)
- 50: e8 fc ff ff ff call 51 <main+0x36>
- 55: 8b 44 24 18 mov 0x18(%esp),%eax
- 59: c9 leave
- 5a: c3 ret
所以说代码编译后的机器指令经常被放在代码段里。
再看一下.bss段,输入命令:
点击(此处)折叠或打开
- objdump -x -s -d 1.o
查看:
点击(此处)折叠或打开
- Sections:
- Idx Name Size VMA LMA File off Algn
- 2 .bss 00000004 00000000 00000000 0000009c 2**2
- ALLOC
看到.bss的大小为4,《程序员自我修养》上说只有static_var2存放到.bss段,而global_uninit_var只是一个未定义的“COMMON符号“没有放在任何段里,这是跟不同的语言与不同的编译器实现有关。看完书后在来补充吧。
最后,说bbs段在文件中不不占用空间,请参考下面代码:
1.
点击(此处)折叠或打开
- #include <stdio.h>
- int main(void)
- {
- return 0;
- }
编译查看大小:
点击(此处)折叠或打开
- root@women:/usr/local/src# gcc -c 1.c
- root@women:/usr/local/src# size 1.o
text data bss dec hex filename
66 0 0 66 42 2.o - root@women:/usr/local/src# ls -l 1.o
- -rw-r--r-- 1 root root 852 8月 27 11:03 2.o
2.比上面代码多了16字节的”int a[10] = {0};“
点击(此处)折叠或打开
- #include <stdio.h>
- int a[10] = {0};
- int main(void)
- {
- return 0;
- }
再来编译查看大小:
点击(此处)折叠或打开
- root@women:/usr/local/src# gcc -c 2.c
- root@women:/usr/local/src# ll 2.o
- -rw-r--r-- 1 root root 868 8月 27 11:13 2.o
- root@women:/usr/local/src# size 2.o
- text data bss dec hex filename
- 66 0 40 106 6a 2.o
两段代码便以后,BSS段大小发生了变化多了40个字节,但是实际文件大小只相差16个字节,刚好就是加入代码的”int a[10] = {0};“这十六个字节。所以说bbs段在文件中不不占用空间。
LINUX下目标文件的BSS段、数据段、代码段的更多相关文章
- Linux下目标文件分析
文章来源:华清远见嵌入式学院,原文地址:http://www.embedu.org/Column/Column699.htm 作者:冯老师,华清远见嵌入式学院讲师. 1. 程序源码如下: 2.命令 g ...
- Linux下搜索文件find、which、whereis、locate
Linux下搜索文件find.which.whereis.locate: - which 寻找“执行文件” - -a 将所有可找到的命令均列出,而不仅仅列出第一个找到的命令名称 - whereis 寻 ...
- linux下各文件夹的结构说明及用途介绍
linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令. /dev:设备特殊文件. /etc:系统管理和配置文件. /etc/rc.d:启动的配 置文件和脚本. /ho ...
- 【转】linux下各文件夹的结构说明及用途介绍
linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令. /dev:设备特殊文件. /etc:系统管理和配置文件. /etc/rc.d:启动的配 置文件和脚本. /home:用户主目录 ...
- Linux下各文件夹的结构说明及用途介绍(转载)
linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令. /dev:设备特殊文件. /etc:系统管理和配置文件. /etc/rc.d:启动的配 置文件和脚本. /home:用户主目录 ...
- linux下各文件夹的结构说明及用途介绍:Linux目录结构介绍
linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令. /dev:设备特殊文件. /etc:系统管理和配置文件. /etc/rc.d:启动的配 置文件和脚本. /home:用户主目录 ...
- linux下的文件类型
在Linux中一切设备皆文件,首先来看一下Linux下的文件都有哪些分类,也就是文件类型 文件类型:普通文件(包括shell脚本,文档,音频,视频).目录文件.设备文件(又细分为字符设备文件和块设备文 ...
- Linux下的文件及文件后缀名
Linux下的文件及文件后缀名 2013-03-14 15:34 6969人阅读 评论(0) 收藏 举报 ++++++++++++++++++++++++++++++++++++++正文+++++++ ...
- Linux Linux下最大文件描述符设置
Linux下最大文件描述符设置 by:授客 QQ:1033553122 1. 系统可打开最大文件描述符设置 查看系统可打开最大文件描述符 # cat /proc/sys/fs/file-max 6 ...
随机推荐
- GBDT 与 XGBoost
GBDT & XGBoost ### 回归树 单棵回归树可以表示成如下的数学形式 \[ f(x) = \sum_j^Tw_j\mathbf{I}(x\in R_j) \] 其中\(T\)为叶节 ...
- 听说你的模型损失是NaN
听说你的模型损失是NaN 有时候,模型跑着跑着,损失就莫名变NaN了.不过,经验告诉我们,大部分NaN主要是因为除数是0或者传给log的数值不大于0.下面说说是log出NaN的几种常见解决方法. 毕竟 ...
- Leetcode 436.寻找右区间
寻找右区间 给定一组区间,对于每一个区间 i,检查是否存在一个区间 j,它的起始点大于或等于区间 i 的终点,这可以称为 j 在 i 的"右侧". 对于任何区间,你需要存储的满足条 ...
- Leetcode 430.扁平化多级双向链表
扁平化多级双向链表 您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示. 扁 ...
- Python 协程、IO模型
1.协程(单线程实现并发)2.I/0模型 2.1阻塞I/O 2.2非阻塞I/O 知识点一:协程 协程的目的:是想要在单线程下实现并发(并发看起来是同时运行的) 并发=多个任务间切换+保存状态(正常情况 ...
- 九度oj 题目1177:查找
题目描述: 读入一组字符串(待操作的),再读入一个int n记录记下来有几条命令,总共有2中命令:1.翻转 从下标为i的字符开始到i+len-1之间的字符串倒序:2.替换 命中如果第一位为1,用命 ...
- Linux下安装Mysql出现的常见问题以及解决办法
1.安装时候出现 warning: mysql-community-server-5.7.13-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ...
- Xcode中断点的使用
注:本文由破船译自:albertopasca.本文由HoNooD在iosfeed站点上做了推荐. 这里先推荐两篇Xcode相关的文章: Xcode Code Snippets iOS调试 — 基本技巧 ...
- [LOJ#113]最大异或和
[LOJ#113]最大异或和 试题描述 这是一道模板题. 给由 n 个数组成的一个可重集 S,求一个集合 T⊆S,使 T1 xor T2 xor … xor T|T| 最大 输入 第一行一个数 n.第 ...
- 第一次使用HTML
1.第一次使用HTML <title>第一次使用HTML</title></head><body>hello,HTML2.文本处理 <title& ...