工具:gcc, objdump, readelf
参考:《程序员自我修养》
代码编译后的机器指令经常被放在代码段里,代码段名为".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 -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
点击(此处)折叠或打开
- 
				Contents of section .data:
 
- 0000 54000000 00000000 55000000 T.......U...
然后我们来看一下.rodata段的数据:
点击(此处)折叠或打开
- 
				Contents of section .rodata:
 
- 
				 0000 68656c6c 6f20776f 726c6421 0025640a  hello world!.%d.
 
- 0010 00323232 323200 .22222.
接下来就是代码段.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$...
点击(此处)折叠或打开
- 
				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
最后,说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
