代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19const 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;
汇编
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
1980000000000400bb6 <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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复