nested_func的参数传递与普通的(顶层翻译单元)函数是一样的。
1,与普通函数最大的不同就是nested_func具有访问外围函数局部变量的能力,这些局部变量存储在调用栈上。
2,另外一点不同是编译后的函数名。
第1点是不能在外围函数之外直接调用nested_func的原因。
第2点是防止直接调用nested_func的机制。
下面的例子,函数a,b,e,f说明参数传递方式。函数main,q说明访问外围函数局部变量的方式。
- int a(void)
- {
- return 1;
- }
- int e(int x)
- {
- return x++;
- }
- int main(void)
- {
- int foo1 = 1;
- int foo2 = 2;
- int foo3 = 3;
- int b(void)
- {
- return 1;
- }
- int f(int x)
- {
- return x++;
- }
- int q(void)
- {
- foo1++;
- foo3++;
- return 0;
- }
- foo2++;
- a();
- b();
- e(1);
- f(1);
- q();
- return 0;
- }
从编译好的反汇编,可以看出nested_func的参数传递与普通函数一样。
粗斜体的部分是与nested_func访问调用栈相关的过程。
很明显,访问外围函数的局部变量时,nested_func汇编代码与外围函数紧耦合,访问了外围函数的调用栈。
这也是可以理解的,因为只有这个nested_func的外围函数能够调用它,因此调用栈是固定的。
- 0000000000400494 :
- 400494: 55 push %rbp
- 400495: 48 89 e5 mov %rsp,%rbp
- 400498: b8 01 00 00 00 mov $0x1,%eax
- 40049d: c9 leaveq
- 40049e: c3 retq
- 000000000040049f :
- 40049f: 55 push %rbp
- 4004a0: 48 89 e5 mov %rsp,%rbp
- 4004a3: 89 7d fc mov %edi,-0x4(%rbp)
- 4004a6: 8b 45 fc mov -0x4(%rbp),%eax
- 4004a9: 83 45 fc 01 addl $0x1,-0x4(%rbp)
- 4004ad: c9 leaveq
- 4004ae: c3 retq
- 00000000004004af :
- 4004af: 55 push %rbp
- 4004b0: 48 89 e5 mov %rsp,%rbp
- 4004b3: b8 01 00 00 00 mov $0x1,%eax
- 4004b8: c9 leaveq
- 4004b9: c3 retq
- 00000000004004ba :
- 4004ba: 55 push %rbp
- 4004bb: 48 89 e5 mov %rsp,%rbp
- 4004be: 48 83 ec 10 sub $0x10,%rsp
- 4004c2: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%rbp)
- 4004c9: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%rbp)
- 4004d0: c7 45 f0 03 00 00 00 movl $0x3,-0x10(%rbp)
- 4004d7: 83 45 fc 01 addl $0x1,-0x4(%rbp)
- 4004db: e8 b4 ff ff ff callq 400494
- 4004e0: e8 ca ff ff ff callq 4004af
- 4004e5: bf 01 00 00 00 mov $0x1,%edi
- 4004ea: e8 b0 ff ff ff callq 40049f
- 4004ef: bf 01 00 00 00 mov $0x1,%edi
- 4004f4: e8 13 00 00 00 callq 40050c
- 4004f9: 48 8d 45 f0 lea -0x10(%rbp),%rax
- 4004fd: 49 89 c2 mov %rax,%r10
- 400500: e8 17 00 00 00 callq 40051c
- 400505: b8 00 00 00 00 mov $0x0,%eax
- 40050a: c9 leaveq
- 40050b: c3 retq
- 000000000040050c :
- 40050c: 55 push %rbp
- 40050d: 48 89 e5 mov %rsp,%rbp
- 400510: 89 7d fc mov %edi,-0x4(%rbp)
- 400513: 8b 45 fc mov -0x4(%rbp),%eax
- 400516: 83 45 fc 01 addl $0x1,-0x4(%rbp)
- 40051a: c9 leaveq
- 40051b: c3 retq
- 000000000040051c :
- 40051c: 55 push %rbp
- 40051d: 48 89 e5 mov %rsp,%rbp
- 400520: 4c 89 d0 mov %r10,%rax
- 400523: 8b 50 04 mov 0x4(%rax),%edx
- 400526: 83 c2 01 add $0x1,%edx
- 400529: 89 50 04 mov %edx,0x4(%rax)
- 40052c: 8b 10 mov (%rax),%edx
- 40052e: 83 c2 01 add $0x1,%edx
- 400531: 89 10 mov %edx,(%rax)
- 400533: b8 00 00 00 00 mov $0x0,%eax
- 400538: c9 leaveq
- 400539: c3 retq
- 40053a: 90 nop
- 40053b: 90 nop
- 40053c: 90 nop
- 40053d: 90 nop
- 40053e: 90 nop
- 40053f: 90 nop
阅读(1984) | 评论(0) | 转发(0) |