欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

目标文件中的几个重要的段

发布时间:2025/6/15 编程问答 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 目标文件中的几个重要的段 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

                  今年来学习一下目标文件。那啥是目标文件呢?简单的说:目标文件就是经过编译和汇编,但没有经过没了链接的文件。看一段测试代码:

#include <stdio.h>int a = 84;//已初始化的全局变量 int b;//未初始化的全局变量void func(int i) {printf("%d\n",i); }int main() {static int c = 85;//已初始化的局部静态变量static int d;//未初始化的局部静态变量int e = 1;//已初始化的局部变量int f;//未初始化局部变量func(c+d+e+f);return e; }

笔者linux下该文件名为test.c,则直接执行gcc -c test.c 命令,生成test.o文件。再看:

[mapan@localhost mapam]$ objdump -h test.o test.o: file format elf64-x86-64Sections: Idx Name Size VMA LMA File off Algn0 .text 00000054 0000000000000000 0000000000000000 00000040 2**2CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data 00000008 0000000000000000 0000000000000000 00000094 2**2CONTENTS, ALLOC, LOAD, DATA2 .bss 00000004 0000000000000000 0000000000000000 0000009c 2**2ALLOC3 .rodata 00000004 0000000000000000 0000000000000000 0000009c 2**0CONTENTS, ALLOC, LOAD, READONLY, DATA4 .comment 0000002e 0000000000000000 0000000000000000 000000a0 2**0CONTENTS, READONLY5 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000ce 2**0CONTENTS, READONLY6 .eh_frame 00000058 0000000000000000 0000000000000000 000000d0 2**3CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

objdump -h 把ELF文件的各个段的基本信息打印出来。

竖着看:

.text为代码段,存放程序源代码编译后的机器指令。

.data为数据段,存放已初始化的全局变量和局部静态变量

.bss为数据段, 存放未初始化的全局变量和局部静态变量

.rodata为只读数据段

.conment为注释信息段

.note.GUN-stack为堆栈段

.eh_frame为调试信息段

横着看:

size为段的长度

File off 为段所在的位置

为了详细了解每个段的内容,我们需要查看反汇编。

[mapan@localhost mapam]$ objdump -s -d test.o test.o: file format elf64-x86-64Contents of section .text:0000 554889e5 4883ec10 897dfcb8 00000000 UH..H....}......0010 8b55fc89 d64889c7 b8000000 00e80000 .U...H..........0020 0000c9c3 554889e5 4883ec10 c745f801 ....UH..H....E..0030 0000008b 15000000 008b0500 0000008d ................0040 04020345 f80345fc 89c7e800 0000008b ...E..E.........0050 45f8c9c3 E... Contents of section .data:0000 54000000 55000000 T...U... Contents of section .rodata:0000 25640a00 %d.. Contents of section .comment:0000 00474343 3a202847 4e552920 342e342e .GCC: (GNU) 4.4.0010 37203230 31323033 31332028 52656420 7 20120313 (Red 0020 48617420 342e342e 372d3138 2900 Hat 4.4.7-18). Contents of section .eh_frame:0000 14000000 00000000 017a5200 01781001 .........zR..x..0010 1b0c0708 90010000 1c000000 1c000000 ................0020 00000000 24000000 00410e10 8602430d ....$....A....C.0030 065f0c07 08000000 1c000000 3c000000 ._..........<...0040 00000000 30000000 00410e10 8602430d ....0....A....C.0050 066b0c07 08000000 .k...... Disassembly of section .text:0000000000000000 <func>:0: 55 push %rbp1: 48 89 e5 mov %rsp,%rbp4: 48 83 ec 10 sub $0x10,%rsp8: 89 7d fc mov %edi,-0x4(%rbp)b: b8 00 00 00 00 mov $0x0,%eax10: 8b 55 fc mov -0x4(%rbp),%edx13: 89 d6 mov %edx,%esi15: 48 89 c7 mov %rax,%rdi18: b8 00 00 00 00 mov $0x0,%eax1d: e8 00 00 00 00 callq 22 <func+0x22>22: c9 leaveq 23: c3 retq 0000000000000024 <main>:24: 55 push %rbp25: 48 89 e5 mov %rsp,%rbp28: 48 83 ec 10 sub $0x10,%rsp2c: c7 45 f8 01 00 00 00 movl $0x1,-0x8(%rbp)33: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # 39 <main+0x15>39: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 3f <main+0x1b>3f: 8d 04 02 lea (%rdx,%rax,1),%eax42: 03 45 f8 add -0x8(%rbp),%eax45: 03 45 fc add -0x4(%rbp),%eax48: 89 c7 mov %eax,%edi4a: e8 00 00 00 00 callq 4f <main+0x2b>4f: 8b 45 f8 mov -0x8(%rbp),%eax52: c9 leaveq 53: c3 retq

objdump的-s参数可以将所有段的内容可以将所有段的内容以十六进制的方式打印出来,-d参数可以将指令的段反汇编。

 

对于Contents of section .text:最左面一列是偏移量,中间4列是十六进制内容,最右面一列是.text段的ASCII码形式。它是对.text的说明。

对于Contents of section .data:里面有2个值,54000000和55000000他们分别是示例代码中变量a和变量c。

对于.bss:

 

2 .bss 00000004 0000000000000000 0000000000000000 0000009c 2**2

它的大小是4,它存放代码示例中变量d,而变量b没有存放在.bss段,这是根编译器的实现有关。这里的变量b存放在.comment段,但是编译单元内部可见的静态变量是存放在.bss段的。
 

 

 

 

参考资料:程序员的自我修养

 

 

 

 

《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

总结

以上是生活随笔为你收集整理的目标文件中的几个重要的段的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。