C++11新特性中的匿名函数Lambda表达式的汇编实现分析(三)

作者:无名    it人知识库   2020-09-14 00:00:00

C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一)

C++11新特性中的匿名函数Lambda表达式的汇编实现分析(二)

Lambda表达式中较复杂的形式如下:

[ capture ] ( params ) -> ret { body }

现在我们构造一个简单的Lambda闭包函数进行分析:

int main()
{
	int c = 10;
	auto lambda = [&] (int a, int b)->int{
		return a + b - c;
	};
	int r = lambda(1, 2);

	return 0;
}

上面的代码中,lambda表达式要求传递两个参数a和b,并按引用捕获c,计算后的结果返回给r。

相应的汇编码如下:

int c = 10;
 mov         dword ptr [ebp-8],0Ah  
	auto lambda = [&] (int a, int b)->int{
		return a + b - c;
	};
 lea         eax,[ebp-8]  
 push        eax  
 lea         ecx,[ebp-14h]  
 call        010E13B0  
	int r = lambda(1, 2);
 push        2  
 push        1  
 lea         ecx,[ebp-14h]  
 call        010E1400  
 mov         dword ptr [ebp-20h],eax  

	return 0;
 xor         eax,eax

显而易见的,和前面两篇文中的一样,这里仅作简要说明:

由于Lambda表达式中捕获了c,因此这里第一个lea指令,向复制函数传递了c的地址,第二条lea指令向复制函数传递了this用于记录捕获对象的地址,

发生调用时,两个push按照stdcall的方式,从右向左压栈。并向表达式传入了this用于寻址。

lambda调用完毕的返回值默认放在eax中,因此,这里最后一个mov意思是将闭包的函数返回值写入r中。

那么,再看看闭包内如何处理传入参数的以及如何返回的?其实就像普通函数一样的原理,以前的博文也说到过函数调用的汇编原理,这里再简单说说吧。

 pop         ecx  
 mov         dword ptr [ebp-8],ecx  
		return a + b - c;
 mov         eax,dword ptr [ebp+8]  
 add         eax,dword ptr [ebp+0Ch]  
 
 mov         ecx,dword ptr [ebp-8]  
 mov         edx,dword ptr [ecx]  
 sub         eax,dword ptr [edx]

参数[ebp+8] = a ;[ebp+0Ch] = b

eax往往是放临时量,edx往往是放地址,按照这个经验,很容易看出,后面两个mov取出*this(得到的是&c)然后从a+b中减去*(&c),结果放在eax中,ret返回后供主函数中的r获取之。


三篇博文的总结:

C++11中lambda表达式在形式上改变了函数的书写,使函数调用更加简洁灵活,闭包函数也是许多高级语言的特性之一。

Lambda表达式并不是一个神奇的东西,万变不离其宗,他仍然是以一个函数的形式存在于汇编中,底层处理和普通函数基本一样。

Lambda表达式和普通函数在源程序的实现上有不同:

    Lambda表达式通常被作为参数传递给另一个函数,它本身作为callback,以此避免在其他地方写出完整函数或使用函数指针。

Lambda表达式和普通函数在汇编层上的实现基本相同:

    最特殊的地方是,当闭包中要使用本身作用域外的变量时,需要进行“捕获”,而捕获其实是通过另一个隐藏的(源代码不可见),我叫它复制函数(或者叫准备函数吧)来实现的,具体实现根据捕获方式的不同而不同,大体上是一系列赋值语句。

    闭包中通过传入的this指针(不能直接使用)对捕获的变量或者对象进行操作。

关于捕获方式中的按值或者按引用的概念,和普通函数一致。

好了,说到这里,Lambda表达式的底层实现基本说到,本系列博文均属原创,感谢开源中国OSChina提供这样一个学习交流的平台,读者如有其它见解,欢迎评论!

最后送大家一句话,也是原创的。

我们不需要重复造轮子,但是我们必须具有造轮子的能力。

本文内容由it人知识库(原文链接:https://m.itpeo.net/15310/3710232.html)本站为各位整理

Tag:特性中的匿名函数表达式汇编实现分析



我要分享:

  • 微信
  • QQ好友
  • QQ空间
  • 新浪微博


热门推荐

[zt]Ajax 和 XML: 五种常见 Ajax 模式

[zt]Ajax 和 XML: 五种常见 Ajax 模式

可立即使用这些非常有用的 Ajax 设计模式 ... ...

MDA:Jean网站上的定义和资源

MDA:Jean网站上的定义和资源

继续纠缠MDA的定义 转自 http://www.sciences.univ-nantes.fr/info/lrsg... ...

Spring Framework 4.0M1 & 3.2.3 发布了[翻译]

Spring Framework 4.0M1 & 3.2.3 发布了[翻译]

今天早上去SpringSource官网,发现Spring Framework 4.0发布了,我认为最重要的两个特性... ...

简单说一下Jfinal Model静态dao对象误用的问题

简单说一下Jfinal Model静态dao对象误用的问题

   最近有很多jfinal的使用者在误用model静态dao,这里简单的说一下这个问题, @... ...

职业生涯第二年回顾(2011.2~2012.2)

职业生涯第二年回顾(2011.2~2012.2)

 算不上什么工作总结和技术总结,只是大致回顾这1年记忆中的事情。    一... ...

使用import简化spring的配置文件 (转载)

使用import简化spring的配置文件 (转载)

Spring中用import导入配置文件 原文地址:使用import简化spring的配置文件 (转载)作者:瓦砾... ...

每天十分钟,十二天入门Python(十)

每天十分钟,十二天入门Python(十)

# __str__() class Dog(object):     de... ...

JQuery:deferred对象的方法

JQuery:deferred对象的方法

(1) $.Deferred() 生成一个deferred对象。 (2) deferred.done() 指... ...

Maven的安装及与eclipse或MyEclipse的关联

Maven的安装及与eclipse或MyEclipse的关联

apache-Maven的下载就不说了,其安装与JDK的安装几乎类似。当然使用Maven的前提是已经安装好了JD... ...

怎么在HiWork中注册团队及添加成员

怎么在HiWork中注册团队及添加成员

周三,天气较热,各位注意身体,多饮水。 使用HiWork,首先要进行团队创建以及成员添加,这样才能愉快地... ...

linux wineQQ与win7QQ共用聊天记录

linux wineQQ与win7QQ共用聊天记录

首先挂载win7硬盘,挂载方法就不介绍了。 然后点开QQ的设置  -> 文件管理 -&g... ...

Clustrix Sierra关系数据库集群

Clustrix Sierra关系数据库集群

Clustrix的Sierra数据库集群引擎是一个share-nothing架构的可伸缩关系数据库集群。官... ...

Android圆了Linux桌面之梦

Android圆了Linux桌面之梦

Google开源主管Chris DiBona在采访中称,Android圆了Linux桌面之梦。 DiBona表示,... ...

系统管理构架

系统管理构架

1. 登录系统(VPN+ssh)。 为了保护系统,登录系统应该有审计,有记录。并且,普通用户只不能在登录... ...

swing 消息框 joptionpane

swing 消息框 joptionpane

4.消息弹出窗口 import javax.swing.JFrame; import javax.sw... ...

swing 消息框 joptionpane

swing 消息框 joptionpane

1.使用JOptionPane提示用户确认 import javax.swing.JOptionPan... ...

Quartz之SimpleTrigger

Quartz之SimpleTrigger

SimpleTrigger: 它只能用于指定任务在一个特定时间内运行,可指定任务的重复(时间,次数)与间隔(时间,次数)... ...

人力资源主管的素质要求

人力资源主管的素质要求

作者:佚名 现代企业的人力资源管理的总趋势是以人为本,本着认识人、尊重人、开发人、激励人的观念,把人看成是一种... ...

C++xml文件操作 CMarkup学习方法说明

C++xml文件操作 CMarkup学习方法说明

   最近正在研究C++下的XML分析工具CMarkup。初次和XML相遇是基于C#对XML的... ...

JS文字滚动效果

JS文字滚动效果

没什么技术难度,主要是Array对象的push()和shift()方法的调用。 一般的实现方法,即直接分别在id为st... ...

最新IT资讯

必填

◎已有 0 人评论


电脑版

版权所有:IT人知识库 m.itpeo.net

返回顶部

本网站部分内容来自互联网,版权归原作者所有,文章内容仅代表原作者个人观点,如有侵权请联系我们删除