win10 + vs2017

源码如下:

int main()

{

  vector< int > numbers = { 1, 2, 3, 4, 5 };

  for (auto num : numbers)

  {

    printf( "num = %d\n", num );

  }

  return 0;

}

汇编理解如下:

int main()
{
# 入栈
00933F63  sub         esp,150h  
00933F69  push        ebx  
00933F6A  push        esi  
00933F6B  push        edi  
00933F6C  lea         edi,[ebp-150h]  
00933F72  mov         ecx,54h  
00933F77  mov         eax,0CCCCCCCCh  
00933F7C  rep stos    dword ptr es:[edi]  
00933F7E  mov         eax,dword ptr [__security_cookie (093E004h)]  
00933F83  xor         eax,ebp  
00933F85  mov         dword ptr [ebp-4],eax

vector< int >    numbers = { 1, 2, 3, 4, 5 };

// memset( &numbers, 0x00, sizeof ( numbers ) );
// sizeof ( numbers ) == 10h
00933F88  push        10h  
00933F8A  lea         ecx,[numbers]  
00933F8D  call        std::vector<int,std::allocator<int> >::__autoclassinit2 (09314ABh)

// [ebp-14Ch, ebp-138h) 这段内存是5个整形(20个字节),分别赋值为1,2,3,4,5
00933F92  mov         dword ptr [ebp-14Ch],1  
00933F9C  mov         dword ptr [ebp-148h],2  
00933FA6  mov         dword ptr [ebp-144h],3  
00933FB0  mov         dword ptr [ebp-140h],4  
00933FBA  mov         dword ptr [ebp-13Ch],5

// 创建allocator对象,供后面vector构造使用,地址为 ebp-111h
00933FC4  lea         ecx,[ebp-111h]  
00933FCA  call        std::allocator<int>::allocator<int> (0931163h)  
00933FCF  push        eax

// std::initializer_list<int> 构造
// initializer_list(const _Elem *_First_arg, const _Elem *_Last_arg)
00933FD0  lea         eax,[ebp-138h]  
00933FD6  push        eax  
00933FD7  lea         ecx,[ebp-14Ch]  
00933FDD  push        ecx  
00933FDE  lea         ecx,[ebp-124h]  
00933FE4  call        std::initializer_list<int>::initializer_list<int> (09314A6h)

// vector 构造
// vector(initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc())
// _Al参数是在 00933FCF 位置压栈的
// _Ilist参数是按值传递,将成员_First和_Last分两次压栈,对应下面4行
00933FE9  mov         edx,dword ptr [eax+4]  
00933FEC  push        edx  
00933FED  mov         eax,dword ptr [eax]  
00933FEF  push        eax  
00933FF0  lea         ecx,[numbers]  
00933FF3  call        std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (0931168h)

for (auto num : numbers)

// std::vector<int,std::allocator<int> >::begin() 结果保存在 dword ptr [ebp-30h]
00933FF8  lea         eax,[numbers]  
00933FFB  mov         dword ptr [ebp-24h],eax  
00933FFE  mov         ecx,dword ptr [ebp-24h]  
00934001  call        std::vector<int,std::allocator<int> >::_Unchecked_begin (09311FEh)  
00934006  mov         dword ptr [ebp-30h],eax

// std::vector<int,std::allocator<int> >::end() 结果保存在 dword ptr [ebp-3Ch]
00934009  mov         ecx,dword ptr [ebp-24h]  
0093400C  call        std::vector<int,std::allocator<int> >::_Unchecked_end (09312C1h)  
00934011  mov         dword ptr [ebp-3Ch],eax

// 跳转 for 循环的条件比较
00934014  jmp         main+0BFh (093401Fh)

// 迭代器加1
00934016  mov         eax,dword ptr [ebp-30h]  
00934019  add         eax,4  
0093401C  mov         dword ptr [ebp-30h],eax

// eax = dword ptr [ebp-30h]
// eax 和 vector::end() 比较,如果相等则跳出循环
0093401F  mov         eax,dword ptr [ebp-30h]  
00934022  cmp         eax,dword ptr [ebp-3Ch]  
00934025  je          main+0E2h (0934042h)

// 将 dword ptr [ebp-30h] 迭代器指向的整形数值取出来,放到 dword ptr [ebp-48h]
00934027  mov         eax,dword ptr [ebp-30h]  
0093402A  mov         ecx,dword ptr [eax]  
0093402C  mov         dword ptr [ebp-48h],ecx  
    {
        printf( "num = %d\n", num );

// 从 dword ptr [ebp-48h] 取出整形数值,压栈
// 将 "num = %d\n" 压栈
// 调用 printf
0093402F  mov         eax,dword ptr [ebp-48h]  
00934032  push        eax  
00934033  push        offset string "num = %d\n" (093BC88h)  
00934038  call        _printf (093153Ch)  
0093403D  add         esp,8  
    }

// 跳转到迭代器加1位置
00934040  jmp         main+0B6h (0934016h)

return 0;
00934042  mov         dword ptr [ebp-130h],0

// vecotr析构
0093404C  lea         ecx,[numbers]  
0093404F  call        std::vector<int,std::allocator<int> >::~vector<int,std::allocator<int> > (0931078h)

// 将返回值0放入eax寄存器
00934054  mov         eax,dword ptr [ebp-130h]  
}

// 出栈
0093405A  push        edx  
0093405B  mov         ecx,ebp  
0093405D  push        eax  
0093405E  lea         edx,ds:[93408Ch]  
00934064  call        @_RTC_CheckStackVars@8 (09313F7h)  
00934069  pop         eax  
0093406A  pop         edx  
0093406B  pop         edi  
0093406C  pop         esi  
0093406D  pop         ebx  
0093406E  mov         ecx,dword ptr [ebp-4]  
00934071  xor         ecx,ebp  
00934073  call        @__security_check_cookie@4 (0931415h)  
00934078  add         esp,150h  
0093407E  cmp         ebp,esp  
00934080  call        __RTC_CheckEsp (0931212h)  
00934085  mov         esp,ebp  
00934087  pop         ebp  
00934088  ret

C++11 initializer_list 和 Range-based for loop 学习理解的更多相关文章

  1. Node.js Event Loop 的理解 Timers,process.nextTick()

    写这篇文章的目的是将自己对该文章的理解做一个记录,官方文档链接The Node.js Event Loop, Timers, and process.nextTick() 文章内容可能有错误理解的地方 ...

  2. 11种常用css样式之border学习

    边框border通常简写为"border:1px solid red;"但其实一个完整的border边框其实是由1.border-width/*边框宽度*/,2.border-st ...

  3. C++11新特性——range for

    很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ...

  4. C++11中自定义range

    python中的range功能非常好用 for i in range(100): print(i) 现在利用C++11的基于范围的for循环特性实现C++中的range功能 class range { ...

  5. c++11::initializer_list

    #include <initializer_list> template <class T> class initializer_list; initializer_list对 ...

  6. getSelection、range 对象属性,方法理解,解释

    网上转了一圈发现没有selection方面的解释,自己捣鼓下 以这段文字为例子.. <p><b>法国国营铁路公司(SNCF)20日承认,</b>新订购的2000列火 ...

  7. 对Node.JS的事件轮询(Event Loop)的理解

    title: Node.JS的事件轮询(event loop)的理解 categories: 理解 tags: Node JS 机制 当我们知道I/O操作和创建新线程的开销是巨大的! 网站延迟的开销 ...

  8. 11个超棒的iOS开发学习网站

    原文:11 Insanely Great iOS Developers Sites 永不止步地向他人学习 我相信,要想从一个"还不错"的人变成一个卓越的人,我们需要不停地向他人学习 ...

  9. 编辑器开发之 Range 范围对象的学习

    写在前面: 网上有各种富文本编辑器,微博分享等操作,这些功能非常实用,他们就是使用 range,selection 对象来实现的,这两个对象偏冷门,不涉及编辑器一般用不到,range 对象是对选区的操 ...

随机推荐

  1. 毕向东_Java基础视频教程第19天_IO流(18~19)

    第19天-18-IO流(流操作规律 - 1) 通过三个步骤来明确"流操作"的规律: 明确数据流的"源和目的" 源, 输入流: InputStream/Reade ...

  2. 用jsp实现网站登录界面的制作,并连接数据库

    课堂测试 任务需求: 撰写一篇博客 需要网站系统开发需要掌握的技术: 本次课堂测试的源程序代码: 运行结果截图: 说明课堂测试未按时完成的原因. 列出你对这门课的希望和自己的目标,并具体列出你计划每周 ...

  3. C#-XML-数据传输

    http://www.cnblogs.com/fengxuehuanlin/p/5631664.html 关于xml是属于一个比较重要的东西,在平时开发的过程中,这块内容最主要的是要掌握XML内容的读 ...

  4. 《深入理解mybatis原理》 Mybatis数据源与连接池

    对于ORM框架而言,数据源的组织是一个非常重要的一部分,这直接影响到框架的性能问题.本文将通过对MyBatis框架的数据源结构进行详尽的分析,并且深入解析MyBatis的连接池. 本文首先会讲述MyB ...

  5. [翻译] Shimmer

    Shimmer Shimmer is an easy way to add a shimmering effect to any view in your app. It's useful as an ...

  6. 将一种cell当做几种cell使用

    将一种cell当做几种cell使用 将一种cell当做几种cell用是有着一些意义的,比如,有时候,不同的cell之间差异很小,如果再派生一个cell出来,就会显得很麻烦,这时候,将这个cell当做几 ...

  7. sort、sorted、heapq、bisect排序

    aa=[1,2,8,7,0,13,28,3]sorted(aa) #原list不变,从小到大排序 aa.sort() #改变原lisaa.sort(reverse=True) #反转 for i in ...

  8. Python学习---ORM查询之基于对象的正向/反向/聚合/分组/Q/F查询

    ORM查询之基于对象的正向查询与反向查询 对象形式的查询 # 正向查询 ret1=models.Book.objects.first() print(ret1.title) print(ret1.pr ...

  9. 最优化 KKT条件

    对于约束优化问题: 拉格朗日公式: 其KKT条件为: 求解 x.α.β 其中β*g(x)为互补松弛条件 KKT条件是使一组解成为最优解的必要条件,当原问题是凸问题的时候,KKT条件也是充分条件.

  10. 初始python(一)

    一.python特性概要 1. python是解释性脚本语言. 2. python特性总结 2.1 字节码 2.2 动态语义 在赋值是确定数据类型 2.3 缩进(4个空格) 3. python定义编码 ...