我是靠谱客的博主 温柔钻石,最近开发中收集的这篇文章主要介绍C++:汇编:函数里return 栈内vector变量时,是怎么走的代码汇编解释,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

代码

const int max_v=100;
const string abc="abc";
//int foo()
//{}
vector<string> foo()
{
        vector<string> abc(max_v,"test");
        return abc;
}
int main()
{
//vector<unique_ptr<abc>> v_s_a;
//unique_ptr<abc> u_s_b (new abc);
//v_s_a.push_back(move(u_s_b));
vector <string> a;
a=foo();
for(auto b:a)
        cout<<b<<endl;

汇编

0000000000400bb6 <foo[abi:cxx11]()>:
  400bb6:       55                      push   %rbp
  400bb7:       48 89 e5                mov    %rsp,%rbp
  400bba:       53                      push   %rbx
  400bbb:       48 83 ec 58             sub    $0x58,%rsp   分配栈空间
  400bbf:       48 89 7d a8             mov    %rdi,-0x58(%rbp)   第一个参数放到 0x58这个位置;就是vector的this 指针。
  400bc3:       48 8d 45 bf             lea    -0x41(%rbp),%rax   分配一个string类型的allocator的对象指针在041 这个位置
  400bc7:       48 89 c7                mov    %rax,%rdi
  400bca:       e8 89 01 00 00          callq  400d58 <allocator<std::basic_string<char, char_traits<char>, allocator<char> > >::allocator()>   分配器,分配string;
  400bcf:       48 8d 45 ef             lea    -0x11(%rbp),%rax   11 这个位置 是做什么? 是一个 allocator对象的地址。
  400bd3:       48 89 c7                mov    %rax,%rdi
  400bd6:       e8 d5 fe ff ff          callq  400ab0 <std::allocator<char>::allocator()@plt>
  400bdb:       48 8d 55 ef             lea    -0x11(%rbp),%rdx   第三个参数,allocator地址
  400bdf:       48 8d 45 c0             lea    -0x40(%rbp),%rax  string 对象地址
  400be3:       be e8 13 40 00          mov    $0x4013e8,%esi   全局字符常量地址
  400be8:       48 89 c7                mov    %rax,%rdi    string 对象指针。
  400beb:       e8 60 fe ff ff          callq  400a50 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)@plt>  、、、构造string
  400bf0:       48 8d 4d bf             lea    -0x41(%rbp),%rcx   string 对象allocator指针
  400bf4:       48 8d 55 c0             lea    -0x40(%rbp),%rdx   string 对象
  400bf8:       48 8b 45 a8             mov    -0x58(%rbp),%rax   vector 对象地址  直接放到了 调用者栈里   !!!!!
  400bfc:       be 64 00 00 00          mov    $0x64,%esi,数量大小。调用 vector的 构造函数构造100 个元素
  400c01:       48 89 c7                mov    %rax,%rdi    vector 对象 this 指针
  400c04:       e8 87 01 00 00          callq  400d90 <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)>
  400c09:       48 8d 45 c0             lea    -0x40(%rbp),%rax   将 rbp-0x40 地址放到rax
  400c0d:       48 89 c7                mov    %rax,%rdi           传入第一个参数,析构 string;
  400c10:       e8 eb fd ff ff          callq  400a00 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@plt>
  400c15:       48 8d 45 ef             lea    -0x11(%rbp),%rax    、、、、 后续就是做析构对象操作。
  400c19:       48 89 c7                mov    %rax,%rdi
  400c1c:       e8 1f fe ff ff          callq  400a40 <std::allocator<char>::~allocator()@plt>
  400c21:       48 8d 45 bf             lea    -0x41(%rbp),%rax
  400c25:       48 89 c7                mov    %rax,%rdi
  400c28:       e8 47 01 00 00          callq  400d74 <std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >  >::~allocator()>
  400c2d:       eb 37                   jmp    400c66 <foo[abi:cxx11]()+0xb0>
  400c2f:       48 89 c3                mov    %rax,%rbx
  400c32:       48 8d 45 c0             lea    -0x40(%rbp),%rax
  400c36:       48 89 c7                mov    %rax,%rdi
  400c39:       e8 c2 fd ff ff          callq  400a00 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@plt>
  400c3e:       eb 03                   jmp    400c43 <foo[abi:cxx11]()+0x8d>
  400c40:       48 89 c3                mov    %rax,%rbx
  400c43:       48 8d 45 ef             lea    -0x11(%rbp),%rax
  400c47:       48 89 c7                mov    %rax,%rdi
  400c4a:       e8 f1 fd ff ff          callq  400a40 <std::allocator<char>::~allocator()@plt>
  400c4f:       48 8d 45 bf             lea    -0x41(%rbp),%rax
  400c53:       48 89 c7                mov    %rax,%rdi
  400c56:       e8 19 01 00 00          callq  400d74 <std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~allocator()>
  400c5b:       48 89 d8                mov    %rbx,%rax
  400c5e:       48 89 c7                mov    %rax,%rdi
  400c61:       e8 3a fe ff ff          callq  400aa0 <_Unwind_Resume@plt>
  400c66:       48 8b 45 a8             mov    -0x58(%rbp),%rax   将-x58 这个地址放到 rax,其实栈上的数据还在。看看调用者怎么用?
  400c6a:       48 83 c4 58             add    $0x58,%rsp
  400c6e:       5b                      pop    %rbx
  400c6f:       5d                      pop    %rbp
  400c70:       c3                      retq


0000000000400e31 <main>:
  400e31:       55                      push   %rbp
  400e32:       48 89 e5                mov    %rsp,%rbp
  400e35:       53                      push   %rbx
  400e36:       48 83 ec 78             sub    $0x78,%rsp
  400e3a:       48 8d 45 b0             lea    -0x50(%rbp),%rax
  400e3e:       48 89 c7                mov    %rax,%rdi
  400e41:       e8 c8 02 00 00          callq  40110e <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector()>
  400e46:       48 8d 45 d0             lea    -0x30(%rbp),%rax   将 rbp-x30地址放到 第一个参数
  400e4a:       48 89 c7                mov    %rax,%rdi
  400e4d:       e8 24 ff ff ff          callq  400d76 <foo[abi:cxx11]()>
  400e52:       48 8d 55 d0             lea    -0x30(%rbp),%rdx   foo 函数创建的 vector,地址。
  400e56:       48 8d 45 b0             lea    -0x50(%rbp),%rax   在 栈上新建 rbp-50 ,vector
  400e5a:       48 89 d6                mov    %rdx,%rsi 
  400e5d:       48 89 c7                mov    %rax,%rdi
  400e60:       e8 c5 02 00 00          callq  40112a <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::operator=(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)>
  400e65:       48 8d 45 d0             lea    -0x30(%rbp),%rax
  400e69:       48 89 c7                mov    %rax,%rdi
  400e6c:       e8 59 02 00 00          callq  4010ca <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~vector()>
  400e71:       48 8d 45 b0             lea    -0x50(%rbp),%rax
  400e75:       48 89 45 e8             mov    %rax,-0x18(%rbp)
  400e79:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  400e7d:       48 89 c7                mov    %rax,%rdi
  400e80:       e8 dd 02 00 00          callq  401162 <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::begin()>
  400e85:       48 89 45 a8             mov    %rax,-0x58(%rbp)
  400e89:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  400e90:       e8 f3 02 00 00          callq  401188 <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, s
td::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::end()>
  400e95:       48 89 45 a0             mov    %rax,-0x60(%rbp)
  400e99:       48 8d 55 a0             lea    -0x60(%rbp),%rdx
  400e9d:       48 8d 45 a8             lea    -0x58(%rbp),%rax
  400ea1:       48 89 d6                mov    %rdx,%rsi
  400ea4:       48 89 c7                mov    %rax,%rdi
  400ea7:       e8 05 03 00 00          callq  4011b1 <bool __gnu_cxx::operator!=<std::__cxx11::basic_string<char, std::char_traits<char>, std::alloc
ator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std
::allocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&, __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_tr
aits<char>, std::allocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)>
  400eac:       84 c0                   test   %al,%al
  400eae:       74 56                   je     400f06 <main+0xd5>
  400eb0:       48 8d 45 a8             lea    -0x58(%rbp),%rax
  400eb4:       48 89 c7                mov    %rax,%rdi
  400eb7:       e8 52 03 00 00          callq  40120e <__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::all
ocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::operator*() const>
  400ebc:       48 89 c2                mov    %rax,%rdx
  400ebf:       48 8d 45 80             lea    -0x80(%rbp),%rax
  400ec3:       48 89 d6                mov    %rdx,%rsi
  400ec6:       48 89 c7                mov    %rax,%rdi
  400ec9:       e8 b2 fc ff ff          callq  400b80 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@plt>
  400ece:       48 8d 45 80             lea    -0x80(%rbp),%rax
  400ed2:       48 89 c6                mov    %rax,%rsi
  400ed5:       bf c0 30 60 00          mov    $0x6030c0,%edi
  400eda:       e8 e1 fc ff ff          callq  400bc0 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@plt>
  400edf:       be 90 0b 40 00          mov    $0x400b90,%esi
  400ee4:       48 89 c7                mov    %rax,%rdi
  400ee7:       e8 04 fd ff ff          callq  400bf0 <std::ostream::operator<<(std::ostream& (*)(std::ostream&))@plt>
  400eec:       48 8d 45 80             lea    -0x80(%rbp),%rax
  400ef0:       48 89 c7                mov    %rax,%rdi
  400ef3:       e8 a8 fc ff ff          callq  400ba0 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@plt>
  400ef8:       48 8d 45 a8             lea    -0x58(%rbp),%rax
  400efc:       48 89 c7                mov    %rax,%rdi
  400eff:       e8 ea 02 00 00          callq  4011ee <__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::all
ocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_stri
ng<char, std::char_traits<char>, std::allocator<char> > > > >::operator++()>
  400f04:       eb 93                   jmp    400e99 <main+0x68>
  400f06:       bb 00 00 00 00          mov    $0x0,%ebx
  400f0b:       48 8d 45 b0             lea    -0x50(%rbp),%rax
  400f0f:       48 89 c7                mov    %rax,%rdi
  400f12:       e8 b3 01 00 00          callq  4010ca <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, s
td::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~vector()>
  400f17:       89 d8                   mov    %ebx,%eax
  400f19:       eb 2b                   jmp    400f46 <main+0x115>
  400f1b:       48 89 c3                mov    %rax,%rbx
  400f1e:       48 8d 45 80             lea    -0x80(%rbp),%rax
  400f22:       48 89 c7                mov    %rax,%rdi
  400f25:       e8 76 fc ff ff          callq  400ba0 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string
()@plt>
  400f2a:       eb 03                   jmp    400f2f <main+0xfe>
  400f2c:       48 89 c3                mov    %rax,%rbx
  400f2f:       48 8d 45 b0             lea    -0x50(%rbp),%rax
  400f33:       48 89 c7                mov    %rax,%rdi
  400f36:       e8 8f 01 00 00          callq  4010ca <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, s
td::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~vector()>
  400f3b:       48 89 d8                mov    %rbx,%rax
  400f3e:       48 89 c7                mov    %rax,%rdi
  400f41:       e8 1a fd ff ff          callq  400c60 <_Unwind_Resume@plt>
  400f46:       48 83 c4 78             add    $0x78,%rsp
  400f4a:       5b                      pop    %rbx
  400f4b:       5d                      pop    %rbp
  400f4c:       c3                      retq

000000000040112a <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::operator=(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)>:   、、、、 move 赋值构造函数
  40112a:       55                      push   %rbp
  40112b:       48 89 e5                mov    %rsp,%rbp
  40112e:       48 83 ec 20             sub    $0x20,%rsp
  401132:       48 89 7d e8             mov    %rdi,-0x18(%rbp)
  401136:       48 89 75 e0             mov    %rsi,-0x20(%rbp)
  40113a:       c6 45 ff 01             movb   $0x1,-0x1(%rbp)
  40113e:       48 8b 45 e0             mov    -0x20(%rbp),%rax   第二个参数传入 remove_reference,去除引用,
  401142:       48 89 c7                mov    %rax,%rdi
  401145:       e8 36 02 00 00          callq  401380 <std::remove_reference<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>::type&& std::move<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::
__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)>
  40114a:       48 89 c2                mov    %rax,%rdx
  40114d:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  401151:       48 89 d6                mov    %rdx,%rsi
  401154:       48 89 c7                mov    %rax,%rdi
  401157:       e8 4e 02 00 00          callq  4013aa <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_move_assign(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&, std::integral_constant<bool, true>)>  右值引用的allocator
  40115c:       48 8b 45 e8             mov    -0x18(%rbp),%rax  右值
  401160:       c9                      leaveq
  401161:       c3                      retq



00000000004013aa <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_str
ing<char, std::char_traits<char>, std::allocator<char> > > >::_M_move_assign(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std
::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&, std::integral_constant<boo
l, true>)>:
  4013aa:       55                      push   %rbp
  4013ab:       48 89 e5                mov    %rsp,%rbp
  4013ae:       53                      push   %rbx
  4013af:       48 83 ec 38             sub    $0x38,%rsp
  4013b3:       48 89 7d c8             mov    %rdi,-0x38(%rbp)
  4013b7:       48 89 75 c0             mov    %rsi,-0x40(%rbp)
  4013bb:       48 8b 55 c8             mov    -0x38(%rbp),%rdx
  4013bf:       48 8d 45 ef             lea    -0x11(%rbp),%rax
  4013c3:       48 89 d6                mov    %rdx,%rsi
  4013c6:       48 89 c7                mov    %rax,%rdi
  4013c9:       e8 84 02 00 00          callq  401652 <std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char
> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::get_allocator() const>
  4013ce:       48 8d 55 ef             lea    -0x11(%rbp),%rdx
  4013d2:       48 8d 45 d0             lea    -0x30(%rbp),%rax
  4013d6:       48 89 d6                mov    %rdx,%rsi
  4013d9:       48 89 c7                mov    %rax,%rdi
  4013dc:       e8 a5 02 00 00          callq  401686 <std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector(std::allocator<std::__cxx11::basic_string<c
har, std::char_traits<char>, std::allocator<char> > > const&)>
  4013e1:       48 8d 45 ef             lea    -0x11(%rbp),%rax
  4013e5:       48 89 c7                mov    %rax,%rdi
  4013e8:       e8 57 fc ff ff          callq  401044 <std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
 >::~allocator()>
  4013ed:       48 8b 45 c8             mov    -0x38(%rbp),%rax
  4013f1:       48 8d 55 d0             lea    -0x30(%rbp),%rdx
  4013f5:       48 89 d6                mov    %rdx,%rsi
  4013f8:       48 89 c7                mov    %rax,%rdi

解释

gcc 分了两步做这个return value的转移:

  1. 在calling function,分配栈地址,传递给foo 函数,作为vector 引用的传递媒介。
  2. 使用 move 赋值 构造函数,并利用 上一步的媒介地址,右值引用,创建新的vector 列表。

汇编里的函数符号真是太长了。
打印输出一下地址看看;地址都是一样的。
10 addr=0x1ca6ff0 50 addr=0x1ca7630
10 addr=0x1ca6ff0 50 addr=0x1ca7630

最后

以上就是温柔钻石为你收集整理的C++:汇编:函数里return 栈内vector变量时,是怎么走的代码汇编解释的全部内容,希望文章能够帮你解决C++:汇编:函数里return 栈内vector变量时,是怎么走的代码汇编解释所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部