C++11 中的 Lambda 表达式
- C++11 中 Lambda 表达式本质上就是一段 机器代码(Code)
- 通过 callq 机器指令进行 Lambda函数 的调用
C++11 中 Lambda 表达式的实现
Lambda 表达式使用
如下所示:
#include <iostream>
int main() {
/*
* 无参无返回值的 lambda 表达式
*/
auto hello = []() -> void{
std::cout << "Hello, World!" << std::endl;
};
/*
* 带参带返回值的 lambda 表达式
*/
auto printI = [](int i) -> int {
std::cout << "printI:" << i << std::endl;
return i;
};
/*
* lambda 表达式的调用
*/
hello();
int result = printI(5);
std::cout << "result is :"<< result <<std::endl;
return 0;
}
Lambda 表达式反汇编分析
Lambda 函数的调用
main() 函数,反汇编后的汇编代码如下所示
通过 callq 指令,跳转到对应的 代码段 Code 中去
Dump of assembler code for function main():
0x00000000080009fe <+0>: push %rbp
0x00000000080009ff <+1>: mov %rsp,%rbp
0x0000000008000a02 <+4>: sub $0x10,%rsp
0x0000000008000a06 <+8>: mov %fs:0x28,%rax
0x0000000008000a0f <+17>: mov %rax,-0x8(%rbp)
0x0000000008000a13 <+21>: xor %eax,%eax
0x0000000008000a15 <+23>: lea -0xe(%rbp),%rax
0x0000000008000a19 <+27>: mov %rax,%rdi
=> 0x0000000008000a1c <+30>: callq 0x800097a <<lambda()>::operator()(void) const>
0x0000000008000a21 <+35>: lea -0xd(%rbp),%rax
0x0000000008000a25 <+39>: mov $0x5,%esi
0x0000000008000a2a <+44>: mov %rax,%rdi
0x0000000008000a2d <+47>: callq 0x80009b2 <<lambda(int)>::operator()(int) const>
0x0000000008000a32 <+52>: mov %eax,-0xc(%rbp)
0x0000000008000a35 <+55>: lea 0x14f(%rip),%rsi # 0x8000b8b
0x0000000008000a3c <+62>: lea 0x2015dd(%rip),%rdi # 0x8202020 <_ZSt4cout@@GLIBCXX_3.4>
0x0000000008000a43 <+69>: callq 0x8000810 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x0000000008000a48 <+74>: mov %rax,%rdx
0x0000000008000a4b <+77>: mov -0xc(%rbp),%eax
0x0000000008000a4e <+80>: mov %eax,%esi
0x0000000008000a50 <+82>: mov %rdx,%rdi
0x0000000008000a53 <+85>: callq 0x8000850 <_ZNSolsEi@plt>
0x0000000008000a58 <+90>: mov %rax,%rdx
0x0000000008000a5b <+93>: mov 0x20156e(%rip),%rax # 0x8201fd0
0x0000000008000a62 <+100>: mov %rax,%rsi
0x0000000008000a65 <+103>: mov %rdx,%rdi
0x0000000008000a68 <+106>: callq 0x8000820 <_ZNSolsEPFRSoS_E@plt>
0x0000000008000a6d <+111>: mov $0x0,%eax
0x0000000008000a72 <+116>: mov -0x8(%rbp),%rcx
0x0000000008000a76 <+120>: xor %fs:0x28,%rcx
0x0000000008000a7f <+129>: je 0x8000a86 <main()+136>
0x0000000008000a81 <+131>: callq 0x8000830 <__stack_chk_fail@plt>
0x0000000008000a86 <+136>: leaveq
0x0000000008000a87 <+137>: retq
End of assembler dump.
Lambda 函数的组成
/*
* 无参无返回值的 lambda 表达式
*/
auto hello = []() -> void{
std::cout << "Hello, World!" << std::endl;
};
上述 Lambda 函数反汇编后的汇编代码如下
直接开辟新的 栈帧(Frame) 执行函数代码
Dump of assembler code for function <lambda()>::operator()(void) const:
=> 0x000000000800097a <+0>: push %rbp
0x000000000800097b <+1>: mov %rsp,%rbp
0x000000000800097e <+4>: sub $0x10,%rsp
0x0000000008000982 <+8>: mov %rdi,-0x8(%rbp)
0x0000000008000986 <+12>: lea 0x1e8(%rip),%rsi # 0x8000b75
0x000000000800098d <+19>: lea 0x20168c(%rip),%rdi # 0x8202020 <_ZSt4cout@@GLIBCXX_3.4>
0x0000000008000994 <+26>: callq 0x8000810 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x0000000008000999 <+31>: mov %rax,%rdx
0x000000000800099c <+34>: mov 0x20162d(%rip),%rax # 0x8201fd0
0x00000000080009a3 <+41>: mov %rax,%rsi
0x00000000080009a6 <+44>: mov %rdx,%rdi
0x00000000080009a9 <+47>: callq 0x8000820 <_ZNSolsEPFRSoS_E@plt>
0x00000000080009ae <+52>: nop
0x00000000080009af <+53>: leaveq
0x00000000080009b0 <+54>: retq
End of assembler dump.