概述
代码
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的转移:
- 在calling function,分配栈地址,传递给foo 函数,作为vector 引用的传递媒介。
- 使用 move 赋值 构造函数,并利用 上一步的媒介地址,右值引用,创建新的vector 列表。
汇编里的函数符号真是太长了。
打印输出一下地址看看;地址都是一样的。
10 addr=0x1ca6ff0 50 addr=0x1ca7630
10 addr=0x1ca6ff0 50 addr=0x1ca7630
最后
以上就是温柔钻石为你收集整理的C++:汇编:函数里return 栈内vector变量时,是怎么走的代码汇编解释的全部内容,希望文章能够帮你解决C++:汇编:函数里return 栈内vector变量时,是怎么走的代码汇编解释所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复