Chinaunix首页 | 论坛 | 博客
  • 博客访问: 590446
  • 博文数量: 83
  • 博客积分: 5453
  • 博客等级: 大校
  • 技术积分: 894
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-10 13:51
文章分类

全部博文(83)

文章存档

2015年(2)

2014年(1)

2013年(1)

2012年(3)

2011年(14)

2010年(7)

2009年(7)

2008年(12)

2007年(17)

2006年(19)

我的朋友

分类: C/C++

2011-12-02 18:08:58

nested_func的参数传递与普通的(顶层翻译单元)函数是一样的。
1,与普通函数最大的不同就是nested_func具有访问外围函数局部变量的能力,这些局部变量存储在调用栈上。  
2,另外一点不同是编译后的函数名。


第1点是不能在外围函数之外直接调用nested_func的原因。
第2点是防止直接调用nested_func的机制。


下面的例子,函数a,b,e,f说明参数传递方式。函数main,q说明访问外围函数局部变量的方式。

  1. int a(void)     
  2. {
  3.   return 1;
  4. }
  5. int e(int x)
  6. {
  7.   return x++;
  8. }
  9. int main(void)
  10. {
  11.   int foo1 = 1;
  12.   int foo2 = 2;
  13.   int foo3 = 3;
  14.   int b(void)
  15.   {
  16.     return 1;
  17.   }
  18.   int f(int x)
  19.   {
  20.     return x++;
  21.   }
  22.   int q(void)
  23.   {
  24.     foo1++;
  25.     foo3++;
  26.     return 0;
  27.   }
  28.   foo2++;
  29.   a();
  30.   b();
  31.   e(1);
  32.   f(1);
  33.   q();
  34.   return 0;
  35. }

 

从编译好的反汇编,可以看出nested_func的参数传递与普通函数一样。

 

粗斜体的部分是与nested_func访问调用栈相关的过程。

很明显,访问外围函数的局部变量时,nested_func汇编代码与外围函数紧耦合,访问了外围函数的调用栈。

这也是可以理解的,因为只有这个nested_func的外围函数能够调用它,因此调用栈是固定的。

 

  1. 0000000000400494 :
  2.   400494:       55                      push   %rbp
  3.   400495:       48 89 e5                mov    %rsp,%rbp
  4.   400498:       b8 01 00 00 00          mov    $0x1,%eax
  5.   40049d:       c9                      leaveq
  6.   40049e:       c3                      retq  
  7. 000000000040049f :
  8.   40049f:       55                      push   %rbp
  9.   4004a0:       48 89 e5                mov    %rsp,%rbp
  10.   4004a3:       89 7d fc                mov    %edi,-0x4(%rbp)
  11.   4004a6:       8b 45 fc                mov    -0x4(%rbp),%eax
  12.   4004a9:       83 45 fc 01             addl   $0x1,-0x4(%rbp)
  13.   4004ad:       c9                      leaveq
  14.   4004ae:       c3                      retq  
  15. 00000000004004af :
  16.   4004af:       55                      push   %rbp
  17.   4004b0:       48 89 e5                mov    %rsp,%rbp
  18.   4004b3:       b8 01 00 00 00          mov    $0x1,%eax
  19.   4004b8:       c9                      leaveq
  20.   4004b9:       c3                      retq  
  21. 00000000004004ba
    :
  22.   4004ba:       55                      push   %rbp
  23.   4004bb:       48 89 e5                mov    %rsp,%rbp
  24.   4004be:       48 83 ec 10             sub    $0x10,%rsp
  25.   4004c2:       c7 45 f4 01 00 00 00    movl   $0x1,-0xc(%rbp)
  26.   4004c9:       c7 45 fc 02 00 00 00    movl   $0x2,-0x4(%rbp)
  27.   4004d0:       c7 45 f0 03 00 00 00    movl   $0x3,-0x10(%rbp)
  28.   4004d7:       83 45 fc 01             addl   $0x1,-0x4(%rbp)
  29.   4004db:       e8 b4 ff ff ff          callq  400494
  30.   4004e0:       e8 ca ff ff ff          callq  4004af
  31.   4004e5:       bf 01 00 00 00          mov    $0x1,%edi
  32.   4004ea:       e8 b0 ff ff ff          callq  40049f
  33.   4004ef:       bf 01 00 00 00          mov    $0x1,%edi
  34.   4004f4:       e8 13 00 00 00          callq  40050c
  35.   4004f9:       48 8d 45 f0             lea    -0x10(%rbp),%rax
  36.   4004fd:       49 89 c2                mov    %rax,%r10
  37.   400500:       e8 17 00 00 00          callq  40051c
  38.   400505:       b8 00 00 00 00          mov    $0x0,%eax
  39.   40050a:       c9                      leaveq
  40.   40050b:       c3                      retq  
  41. 000000000040050c :
  42.   40050c:       55                      push   %rbp
  43.   40050d:       48 89 e5                mov    %rsp,%rbp
  44.   400510:       89 7d fc                mov    %edi,-0x4(%rbp)
  45.   400513:       8b 45 fc                mov    -0x4(%rbp),%eax
  46.   400516:       83 45 fc 01             addl   $0x1,-0x4(%rbp)
  47.   40051a:       c9                      leaveq
  48.   40051b:       c3                      retq  
  49. 000000000040051c :
  50.   40051c:       55                      push   %rbp
  51.   40051d:       48 89 e5                mov    %rsp,%rbp
  52.   400520:       4c 89 d0                mov    %r10,%rax
  53.   400523:       8b 50 04                mov    0x4(%rax),%edx
  54.   400526:       83 c2 01                add    $0x1,%edx
  55.   400529:       89 50 04                mov    %edx,0x4(%rax)
  56.   40052c:       8b 10                   mov    (%rax),%edx
  57.   40052e:       83 c2 01                add    $0x1,%edx
  58.   400531:       89 10                   mov    %edx,(%rax)
  59.   400533:       b8 00 00 00 00          mov    $0x0,%eax
  60.   400538:       c9                      leaveq
  61.   400539:       c3                      retq  
  62.   40053a:       90                      nop
  63.   40053b:       90                      nop
  64.   40053c:       90                      nop
  65.   40053d:       90                      nop
  66.   40053e:       90                      nop
  67.   40053f:       90                      nop
阅读(1947) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~