C++11新特性中的匿名函数Lambda表达式的汇编实现分析(二)
2019独角兽企业重金招聘Python工程师标准>>>
C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一)
首先,让我们来看看以&方式进行变量捕获,同样没有参数和返回。
int main()
{int a = 0xB;auto lambda = [&]{a = 0xA;};lambda();return 0;
}
闭包中将main中a变量改写为0xA。
main中的关键汇编代码:
int a = 0xB;mov dword ptr [ebp-8],0Bh auto lambda = [&]{a = 0xA;};lea eax,[ebp-8] push eax lea ecx,[ebp-14h] call 002D1BE0 lambda();lea ecx,[ebp-14h] call 002D1C20 return 0;
同样的,进入闭包前要调用一个拷贝函数。
002D1BE0 内:
pop ecx mov dword ptr [ebp-8],ecx mov eax,dword ptr [ebp-8] mov ecx,dword ptr [ebp+8] mov dword ptr [eax],ecx mov eax,dword ptr [ebp-8] pop edi pop esi pop ebx mov esp,ebp pop ebp ret 4
和前面一篇文章中的代码基本一致,但是有两个地方不同,
上文写到:
pop ecx
mov dword ptr [ebp-8],ecx
mov eax,dword ptr [ebp-8]
mov ecx,dword ptr [ebp+8]
mov edx,dword ptr [ecx]
mov dword ptr [eax],edx
mov eax,dword ptr [ebp-8]
注意黑体部分,若采用[=]的捕获方式,那么将通过寄存器edx拷贝原变量的值;
若采用[&]方式,则直接通过ecx拷贝原变量的地址,而不取出值。
闭包内:
pop ecx mov dword ptr [ebp-8],ecx a = 0xA;mov eax,dword ptr [ebp-8] mov ecx,dword ptr [eax] mov dword ptr [ecx],0Ah };pop edi pop esi pop ebx mov esp,ebp pop ebp ret
对a进行赋值,直接是:
*this = 0xA;
因为事先this就取到了a的地址。
可以发现,按引用捕获实际上就如同函数参数传递引用,传递的是一个地址值,而不创建对象副本(可以和上一篇文中的内容比较)。
C++11标准中对Lambda表达式的捕获内容还有一些特定支持,比如可以以指定的方式捕获指定的变量:
int main()
{int a = 0xB;bool b = true;auto lambda = [&a,b]{a = b;};lambda();return 0;
}
上面的代码对a进行引用捕获,对b按值捕获。根据前面分析的结果,可以预见,a的地址和b的值将被拷贝以供闭包函数使用。
int a = 0xB;mov dword ptr [ebp-8],0Bh bool b = true;mov byte ptr [ebp-11h],1 auto lambda = [&a,b]{a = b;};lea eax,[ebp-11h] push eax lea ecx,[ebp-8] push ecx lea ecx,[ebp-24h] call 00222060 lambda();lea ecx,[ebp-24h] lambda();call 00221C20 return 0;
调用Lambda之前,先调用复制函数,传入两个参数,&a和&b,而this被放在main的[ebp-24h]中。
复制函数或者叫准备函数:
pop ecx mov dword ptr [ebp-8],ecx mov eax,dword ptr [ebp-8] mov ecx,dword ptr [ebp+8] mov dword ptr [eax],ecx mov eax,dword ptr [ebp-8] mov ecx,dword ptr [ebp+0Ch] mov dl,byte ptr [ecx] mov byte ptr [eax+4],dl mov eax,dword ptr [ebp-8] pop edi pop esi pop ebx mov esp,ebp pop ebp ret 8
[eax] 就是 *this,也即a
[eax+4] 就是 *(this+4),也即b
从内存图可以清楚的看到,a的地址被记录,b的值被复制
闭包函数内:
pop ecx mov dword ptr [ebp-8],ecx a = b;mov eax,dword ptr [ebp-8] movzx ecx,byte ptr [eax+4] mov edx,dword ptr [ebp-8] mov eax,dword ptr [edx] mov dword ptr [eax],ecx
b的值是从[eax+4]也即this+4中取出,而a在this中,其实就是:
*(this) = *(this+4);
可以看到闭包内通过this作为基址,对闭包外的变量进行偏移访问。
下一篇中,我将对具有参数和返回值的Lambda表达式进行分析。
转载于:https://my.oschina.net/ybusad/blog/277584
C++11新特性中的匿名函数Lambda表达式的汇编实现分析(二)相关推荐
- 【Kotlin】Kotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )
文章目录 一.函数头声明 二.函数参数 1.默认参数值 2.具名参数 三.Unit 函数 四.TODO 函数抛出异常返回 Nothing 类型 五.反引号函数名 六.匿名函数 七.匿名函数的函数类型 ...
- python匿名函数的作用_Python匿名函数 Lambda表达式作用
在Python这门优美的编程语言中,支持一种有趣的语法格式(表达式),可以让我们在单行内创建一个最小的函数-python lambda匿名函数. 据说是借鉴了Lisp语言中lambda表达式,它可以使 ...
- 14_python基础—匿名函数lambda表达式
文章目录 一.lambda 表达式 1.1 lambda的应用场景 1.2 lambda语法 快速入门 1.3 示例:计算a + b 1.3.1 函数实现 1.3.2 lambda实现 1.4 lam ...
- Scala匿名函数Lambda表达式详解
1 前言 大家好,我是楚生辉,在未来的日子里我们一起来学习大数据相关的技术,一起努力奋斗,遇见更好的自己! 本文详细的介绍了scala的匿名函数,有需要的小伙伴可以学习~ Scala 中定义匿名函数的 ...
- python中的匿名函数lambda
匿名函数 python 使用 lambda 来创建匿名函数. 所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数. lambda 只是一个表达式,函数体比 def 简单很多. lambda ...
- Java笔记整理五(Iterator接口,泛型,常见数据结构(栈,队列,数组,链表,红黑树,集合),jdk新特性,异常,多线程,Lambda表达式)
Java笔记整理五 1.1Iterator接口 Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象 ...
- λ表达式_Java 8新特性:学习如何使用Lambda表达式,一看必懂
我将分为两篇系列文章来描述了使用Java 8的新特性 - lambda表达式. 目录 介绍 我们为什么需要lambdas? Lambdas的语法 功能接口 方法参考 构造函数参考 可变范围 默认方法 ...
- 使用Java8新特性(stream流、Lambda表达式)实现多个List 的笛卡尔乘积 返回需要的List<JavaBean>
需求分析: 有两个Long类型的集合 : List<Long> tagsIds; List<Long> attributesIds; 现在需要将这两个Long类型的集合进行组合 ...
- Python匿名函数——lambda表达式
如果要定义的函数很简单,一个return语句就能搞定,可以使用lambda表达式来定义, lambda表达式的语法如下: lambda parameters: expression lambda表达式 ...
最新文章
- python第二天练习题
- 图卷积网络进行骨骼识别代码_【骨骼行为识别】2s-AGCN论文理解
- Flink从入门到精通100篇(八)-美团点评是如何在 Flink平台建立 实时数仓的?
- php 将date转换成string,php如何实现date转string
- Java中File类的createNewFile、mkdir与mkdirs区别
- ITK:两幅图像之差的绝对值
- windows系统内实现端口转发
- python爬取b站403_Python如何爬取b站热门视频并导入Excel
- 部署邮件服务器之间相互通信
- Android 下拉刷新上拉载入 多种应用场景 超级大放送(上)
- Palo Alto Networks下一代安全平台五大创新功能:云安全为重中之重
- web开发模式+三层架构与MVC
- 高性能mysql sakila_《高性能MySQL》读书笔记二
- vb代码转为c++代码_vb代码转为c++代码_VB源码转换工具(VBto Converter)
- iNFTnews | 元宇宙进行时:那些跑步入场的互联网大厂在如何谋篇布局?
- GO的lua虚拟机 gopher-lua
- Atlassian与DevOps 系列产品选择方案介绍
- centos7搭建bugzilla
- Java实现 LeetCode 492 构造矩形
- 计算机科学与技术研究机构名称,计算机科学与技术学院研究生团队获得SemEval-2021国际语义评测比赛Task 5第一名...
热门文章
- windows环境运行MongoDB
- Basic Windbg - 1. SOSBasics(再续)
- python日历gui_python GUI库图形界面开发之PyQt5日期时间控件QDateTimeEdit详细使用方法与实例...
- mvc mvp mvvm
- Metasploit设置HttpTrace参数技巧
- Xamarin图表开发基础教程(12)OxyPlot框架支持的金融图表类型
- iOS11开发教程(二十三)iOS11应用视图实现按钮的响应(3)
- Xamarin iOS项目找不到模拟器
- php拷贝mysql表_MySQL复制表数据或表结构到新表中
- 龙将加速浏览器_《看门狗:军团》即将开启预载,迅游加速器支持下载和联机加速 18183手机游戏网...