当前位置: 移动技术网 > IT编程>开发语言>PHP > C++11 initializer_list 和 Range-based for loop 学习理解

C++11 initializer_list 和 Range-based for loop 学习理解

2019年03月07日  | 移动技术网IT编程  | 我要评论

www.8181.cm,一七红馆,北京市财政局网

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  

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网