Chinaunix首页 | 论坛 | 博客

分类: C/C++

2011-10-21 08:49:30

作为对http://hi.baidu.com/ypns/blog/item/870f0846db6899026a63e523.html此处的回应。
4 #include
  5 void fun(int t);
  6
  7 int  main()
  8 {
  9         int g;
 10         for(g = 3; g > 1; g--)
 11                 fun(g);
 12         printf("%d\n", g);
 13         return 0;
 14 }
 15 void fun(int t)
 16 {
 17         static int i = 3;  /*在vc下,这里的值是可以赋给一个变量的,但是在gcc下,却只能为常量*/
 18         i = t;
 19         i++;
 20         printf("%d", i);
 21 }
/*这是代码*/
实验结果为:
./static
431           /*从结果可以看出,这个值没有一直自加成功*/
分析下objdump下的汇编。
080483a4
:
 80483a4:       8d 4c 24 04             lea    0x4(%esp),%ecx
 80483a8:       83 e4 f0                and    $0xfffffff0,%esp
 80483ab:       ff 71 fc                pushl  0xfffffffc(%ecx)  /*这些初始化如果感兴趣,我前面博客有过分析*/
 80483ae:       55                      push   %ebp
 80483af:       89 e5                   mov    %esp,%ebp
 80483b1:       51                      push   %ecx 
 80483b2:       83 ec 24                sub    $0x24,%esp
 80483b5:       c7 45 f8 03 00 00 00    movl   $0x3,0xfffffff8(%ebp) /*将0x3放入%ebp - 8的地方,符合谁调用谁最后释放的原则*/
 80483bc:       eb 0f                   jmp    80483cd   /*这是for循环的一个比较*/
 80483be:       8b 45 f8                mov    0xfffffff8(%ebp),%eax /*将g那个值放入eax寄存器*/
 80483c1:       89 04 24                mov    %eax,(%esp)  /*将此值放入堆栈栈顶*/
 80483c4:       e8 2b 00 00 00          call   80483f4 /*调用函数*/
 80483c9:       83 6d f8 01             subl   $0x1,0xfffffff8(%ebp) /*返回后减一操作*/
 80483cd:       83 7d f8 01             cmpl   $0x1,0xfffffff8(%ebp) /*这是作比较*/
 80483d1:       7f eb                   jg     80483be /*如果比0x1大的话,就去80483be*/
 80483d3:       8b 45 f8                mov    0xfffffff8(%ebp),%eax
 80483d6:       89 44 24 04             mov    %eax,0x4(%esp)
 80483da:       c7 04 24 00 85 04 08    movl   $0x8048500,(%esp)
 80483e1:       e8 d2 fe ff ff          call   80482b8
 80483e6:       b8 00 00 00 00          mov    $0x0,%eax
 80483eb:       83 c4 24                add    $0x24,%esp
 80483ee:       59                      pop    %ecx
 80483ef:       5d                      pop    %ebp
 80483f0:       8d 61 fc                lea    0xfffffffc(%ecx),%esp
 80483f3:       c3                      ret   

080483f4 :
 80483f4:       55                      push   %ebp  /*入栈esp - 4*/
 80483f5:       89 e5                   mov    %esp,%ebp /*esp 的值作为新栈底*/
 80483f7:       83 ec 08                sub    $0x8,%esp /*分配堆栈*/
 80483fa:       8b 45 08                mov    0x8(%ebp),%eax /*注意这里,这个是取前面的栈顶的那个参数,这里就是那个函数虚拟参数传送机制*/
 80483fd:       a3 78 96 04 08          mov    %eax,0x8049678/*因为是static 所以会在静态数据段存储区,这里直接用地址访问就是那个 i==
Contents of section .data:
 8049674 00000000 03000000   */
 8048402:       a1 78 96 04 08          mov    0x8049678,%eax
 8048407:       83 c0 01                add    $0x1,%eax
 804840a:       a3 78 96 04 08          mov    %eax,0x8049678 /*送回数据存储区*/
 804840f:       a1 78 96 04 08          mov    0x8049678,%eax
 8048414:       89 44 24 04             mov    %eax,0x4(%esp)
 8048418:       c7 04 24 04 85 04 08    movl   $0x8048504,(%esp)  /* Contents of section .rodata:
 80484f4 03000000 01000200 00000000 25640a00  ............%d..
 8048504 256400                               %d.     输出数据前面的格式等信息*/
 804841f:       e8 94 fe ff ff          call   80482b8
 8048424:       c9                      leave 
 8048425:       c3                      ret   

/*从分析的过程来看,这个值被改变了,在循环中。*/
之所以它的值和其他的局部变量不一样的原因是:它在数据存储区,而局部变量在堆栈上。生命周期不同。
static 生命周期在函数调用结束后,其空间不释放,想想怎么释放数据区的空间。
而局部变量会在函数再次调用时,被从新分配,分配地址和原来相同?

阅读(1456) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~