本文主要是介绍static 变量存放在.data还是.bss,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
来自:http://hi.baidu.com/zkheartboy/blog/item/12cc5c904f42e68ba877a472.html
#include <stdio.h> void add() { static int var; var++; printf("var=%d\n",var); } int main() { add(); return 0; } /* //汇编之后 .file "seeStatic.c" .local var.0 .comm var.0,4,4 .section .rodata .LC0: .string "var=%d\n" .text .globl add .type add,@function add: pushl %ebp movl %esp, %ebp subl $8, %esp incl var.0 subl $8, %esp pushl var.0 pushl $.LC0 call printf addl $16, %esp leave ret .Lfe1: .size add,.Lfe1-add .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp call add movl $0, %eax leave ret .Lfe2: .size main,.Lfe2-main .ident "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)" */ //--------------------------------------------------------------------------------------------------------------------------------------------- /*网上的 资料 ChinaUnix.net gerysand 2005-4-15 04:24 关于堆,栈,动态分配,静态分配的一个小实验 其中有些不明白,大家帮着解释一下 下边是c源码 char *str_g="abcd"; int a=0; int b; int main() { static int c; char *str_l=(char *)malloc(16); c=b=a; printf("address of str_l=%x\n",&str_l); printf("address of malloc string=%x\n",str_l); } gerysand 2005-4-15 04:51 关于堆,栈,动态分配,静态分配的一个小实验 编译后的汇编 .file "test.c" //指出这个文件由test.c编译而来 .section .rodata //只读段包含字符"abcd" .LC0: .string "abcd" .globl str_g //全局变量str_g .data //表明在数据段中 .align 4 .type str_g, @object .size str_g, 4 str_g: .long .LC0 //初始化为.LC0的地址,即"abcd"字符串的地址 .globl a //全局变量a .bss //为什么它放在bss数据段中?(还是我理解的有问题) .align 4 .type a, @object .size a, 4 a: .zero 4 //长度为4个字节,初始化为0(是这个意思吗?) .local c.0 //用local标记的static变量c,这个是static定义所特有的,表示虽然放在全局区域但是不可导出 .comm c.0,4,4 //用comm标记应该是表示未初始化,但是后边0,4,4表示什么无从考证 .section .rodata //又是两个字符串常量,用rodata标记为只读数据段 .LC1: .string "address of str_l=%x\n" //.LC1长度为21byte .LC2: .string "address of malloc string=%x\n" .text .globl main //全局函数入口 .type main, @function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp subl $12, %esp pushl $16 call malloc addl $16, %esp movl %eax, -4(%ebp) movl a, %eax movl %eax, b movl %eax, c.0 subl $8, %esp leal -4(%ebp), %eax pushl %eax pushl $.LC1 call printf addl $16, %esp subl $8, %esp pushl -4(%ebp) pushl $.LC2 call printf addl $16, %esp leave ret .size main, .-main //计算main的大小 .comm b,4,4 //为什么b放在这里定义???难道它是放在text段里吗???comm应该是指未初始化 .section .note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.3.2 20031022 (Red Hat Linux 3.3.2-1)" 用bojdump -d 查看的.o文件 test.o: 文件格式 elf32-i386 反汇编 .text 节: 00000000 <main>;: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 08 sub $0x8,%esp 6: 83 e4 f0 and $0xfffffff0,%esp 9: b8 00 00 00 00 mov $0x0,%eax e: 29 c4 sub %eax,%esp 10: 83 ec 0c sub $0xc,%esp 13: 6a 10 push $0x10 15: e8 fc ff ff ff call 16 <main+0x16>; 1a: 83 c4 10 add $0x10,%esp 1d: 89 45 fc mov %eax,0xfffffffc(%ebp) 20: a1 00 00 00 00 mov 0x0,%eax 25: a3 00 00 00 00 mov %eax,0x0 2a: a3 04 00 00 00 mov %eax,0x4 2f: 83 ec 08 sub $0x8,%esp 32: 8d 45 fc lea 0xfffffffc(%ebp),%eax 35: 50 push %eax 36: 68 05 00 00 00 push $0x5 //对应.LC1 3b: e8 fc ff ff ff call 3c <main+0x3c>; //为什么一样的二进制代码和下一个printf调用翻译出来的汇编不一样???见4e地址处 //用objdump -r 查看了一下,发现printf是需要重定位的,但是应该重定向到同一位置 //为什么会出现地址不一样的情况,请高手解答 40: 83 c4 10 add $0x10,%esp 43: 83 ec 08 sub $0x8,%esp 46: ff 75 fc pushl 0xfffffffc(%ebp) 49: 68 1a 00 00 00 push $0x1a //对应.LC2,和LC1相差21byte 4e: e8 fc ff ff ff call 4f <main+0x4f>; 53: 83 c4 10 add $0x10,%esp 56: c9 leave 57: c3 ret */ 从中学习到了 static 声明的变量,不管它是全局变量也好,还是在函数之中的也好,只要是没有赋初值 都存放在.bss段,如果赋了初值,则把它放在.data段。 反汇编的方法, 首先 gcc -o test.o -c test.c 得到test.o文件,然后,objdump -d test.o 即可。 |
这篇关于static 变量存放在.data还是.bss的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!