cpp学习-第三章-字符串向量与数组

核心简记

  1. 安全的命名引入方式: using 命名空间名:要引入的名字; 每句只引入一个成员
  2. string、vector: 标准库类型,见下
  3. c++对库的实现做了性能要求
  4. 拷贝构造和赋值有根本的不同,完全俩个操作,在类中可以分别定义。拷贝初始化与直接构造是俩个操作,拷贝初始化和直接初始化区别在是否有=。拷贝初始化只是传一个参,和直接把那个参传到直接构造里效果是一样的。都是构造的罗列之后去选对应的构造,直接构造是自己填实参选择,拷贝初始化是传一个参数。
  5. string类动态增长是重新分配并拷贝实现的
  6. 迭代器:定义于容器的的访问器,std实现的类。见下
  7. 泛型编程:编写的代码可以作用不同的类型、场所。一句通用。c++经常使用!=与==为条件而不是<<=>=>,是因为所有标准库容器都定义了!=与==,但<>就不一定了,类似的还有迭代器与下标访问。
  8. ->是(*).的简写。.的优先级高于*所以加()

string

位于库:

1
2
#include <string>
using std::string;

初始化方式:

1
2
3
4
5
6
string s1;//默认构造
string s2(s1);//直接构造
string s2=s1;//拷贝初始化
string s3("1234");//直接构造
string s3="1234";//拷贝初始化
string s4(n,'c');//直接构造

这些初始化方式都是类内自定义的,c++可以使类类型像内置类型一样好用。
string对象的操作:

1
2
3
4
5
6
7
8
9
10
11
OS<<s; s写到输出流
is>>s; 从输入流中读入s,以空白符做分割
getline(is,s); 读取一行 舍弃\n
s.empty(); s为空返回true
s.size(); s中字符个数
s[n]; 返回s的第n个字符引用-表示的是指向哪一个
s1+s2; 返回s1与s2连接,要求二者有一个是string,""才能转化为string
s1=s2; s2的副本代替s1中的字符
s1==s2; 比较:先异后长
s1!=s2;
< <= >= >

可定义操作:函数、运算符。判断字符可用cctype库
注意size返回的是string::size_type类型,该类型为无符号类型值。为了标准库类型与机器无关。
c++的字面值字串与string类型不同,字面值是const char *
c++兼容了c语言标准库:xxx.h名为cxxx。二者是一样的,不过在cxxx中定义的名字属于std命名空间。为区分模块与方便应该使用cxxx

范围for语句:

1
2
3
4
5
6
7
8
9
10
for(声明:表达式)
for(auto c : str)
{
遍历str,每次c被初始化为下一个元素,为拷贝
}
for(auto &c : str)
{
遍历str,每次初始化绑定下一个。可修改源
}

用于遍历序列中的每个元素。不是迭代器。范围for内不应该改变其所遍历的序列的大小

问题:

  1. string的内在字串存储表示?可增长的?在栈中的对象样子?可增长?
  2. 直接构造与拷贝初始化的不同?string重载了=

string类动态增长是重新分配并拷贝实现的

vector

容器一种,对象的集合。类模板

1
2
3
4
5
#include<vector>
using std::vector;
vector<int> a;a放int的对象
vector<vector<int>> b;b的元素是vector对象

编译器根据模板创建类或函数称实例化。对象为定义。编译时多态。
vector容纳类型的对象作为元素,引用不是对象所以不存在包含引用的vector。
初始化:

1
2
3
4
5
6
7
vector<T> v1; 空的vector
vector<T> v2(v1); 直接构造
vector<T> v2=v1; 拷贝
vector<T> v3(n,val); n个重复的val
vector<T> v4(n); n个默认初始化的对象
vector<T> v5{a,b,c...}; 列表初始化
vector<T> v5={a,b,c...};

类内初始值初始化只能拷贝初始化或花括号初始化。()是构造对象,{}是列表初始化对象。

vector的操作:

1
2
3
4
5
6
7
8
9
v.empty(); 不含元素返回ture
v.size(); 返回v的元素个数
v.push_back(t); 向尾端添加值为t的元素
v[n]; 返回v中第n个位置上的引用,只能访问已存在的。不可用于添加
v1=v2; v2拷贝替换v1元素
v1={a,b,c,d}; 列表拷贝替换v1元素
v1==v2; 比较,先异后长,元素类型应该定义了比较才可
v1!=v2;
<<=>=>

可以用范围for,size_type是每个类定义一个,这里返回的是vector::size_type

迭代器

所有标准库容器都可以使用迭代器,类似指针实现的类,用于访问容器元素。
有效的迭代器指向某个元素或尾元素的下一个。

1
2
b=v.begin();//返回指向第一个元素的迭代器
e=v.end();//返回指向尾元素下一个位置的迭代器-实际不指向元素,只是标记

运算符:标准库容器类的迭代都实现了的

1
2
3
4
5
6
*it;//返回迭代器指向元素的引用
it->mem;//相当于(*it).mem
++it;//指向下一个元素
--it;//指向上一个元素
it1==it2;//迭代器是否相等,指同一个元素为相等
it1!=it2;

迭代器的类型:

1
2
3
4
vector<int>::iterator it;//读写向量元素
string::iterator it;
vector<int>::const_iterator it;//只能读元素
string::const_iterator it;

都是在各自类下定义的类。类的实现让它与指针一样好用,指的是vector是否const。
const的对象begin与end返回的是const迭代器,其它返回普通。普通想返回const的可以用cbegin()与cend()
使用迭代器时不要改变容器对象大小

迭代器运算:string与vector提供额外的运算符

1
2
3
4
5
6
it+n;//返回向后移动n个元素
it-n;//返回向前移动n个
it+=n;
it-=n;
it1-it2;//相差。自定义的类型
<<=>=>

数组

内置的复合类型,大小不变。数组元素个数也是数组类型的一部分。不能auto,元素为对象,不能是引用。
初始化:

1
2
3
4
5
6
int a[3]={0,1,2};
int b[]={0,1,2,3};
int c[5]={0,1};//等于{0,1,0,0,0}
//字符数组有特殊的初始化形式
char a[]="asafd";//用字面值初始化
const char a[]="13124214";

不允许拷贝赋值。

复杂的声明;

1
2
3
int *p[13];//指针数组
int (*p)[4];//数组指针
int (&p)[4];//数组引用

左右归约形成的语法树是一样的,这是语法规定的解析方式,()改变了语法树的样子。理解的话是从内到外,从右到左。
可以使用范围for与下标,都是c++语言直接定义的。因为维度是数组的一部分,所以范围for可以

数组在编译时编译器一般会把它转化为指针。数组含大小但是指针不含。注意:指针也是迭代器,可以使用迭代器所有的功能,甚至[]

c风格的字串理解为为const char *类型的,不建议使用,c++用string。可以使用字面值初始化string,

使用数组可以初始化vector:

1
vector<int> vec(begin(intarr),end(intarr));//这俩个函数是标准库的,可以传指针只初始化一部分数组

尽量使用标准库

多维数组是数组的数组

1
2
int a[3][4];//内到外理解
int a[3][4]={{0},{1},{2}};//可以每个行初始化一个

指针不保存数组长度,指针只保存类型,数组类型含长度
a[3]表示的是一个int *的指针,一个int [4]的数组
a表示的是一个int (*)[4]的指针,一个int [3][4]的数组
因为auto会把数组类型当指针,因此慎用auto处理数组

反编译

代码:

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
#include <string>
#include <iostream>
#include <vector>
using std::string;using std::cin;using std::cout;
int main()
{
string s;
cin>>s;
string s1;//默认构造
string s2(s1);//直接构造
string s3=s1;//拷贝初始化
//都是传一个、同类型的参,因此调用的构造都一样,拷贝构造不是特殊形式定义的
string s4("1234");//直接构造
string s5="1234";//拷贝初始化
s5=s1;//赋值
//范围for
for(auto t:s)
{
cout<<t<<std::endl;
}
for(auto &t:s)
{
cout<<t<<std::endl;
}
//普通for与迭代
for(auto it=s4.begin();it!=s4.end();++it)
{
cout<<*it<<std::endl;
}
//布尔运算
int i1=0;
bool b1=i1==1&&true;
//向量
std::vector<int> vec;
vec.push_back(3);
vec[0]=1;
//迭代器
auto veci=vec.begin();
//数组auto
int a[5]={1,2,3,4,5};
for(auto i:a)
{
cout<<i<<" ";
}
//多维数组
int a2[3][4]={0};
a2[2][3]=1;
}

x86-64

指令简记

movsx是带符号扩展的转移,也就是说不够的位数用符号补齐

SSE有8个128位独立寄存器(XMM0~XMM7).

分析

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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
.text:0000000000001090 sub_1090 proc near ; DATA XREF: start+2E↑o
.text:0000000000001090
.text:0000000000001090 var_274 = dword ptr -274h
.text:0000000000001090 var_270 = qword ptr -270h
.text:0000000000001090 var_261 = byte ptr -261h
.text:0000000000001090 var_260 = qword ptr -260h
.text:0000000000001090 var_258 = qword ptr -258h
.text:0000000000001090 var_250 = qword ptr -250h
.text:0000000000001090 var_248 = qword ptr -248h
.text:0000000000001090 var_240 = qword ptr -240h
.text:0000000000001090 var_238 = qword ptr -238h
.text:0000000000001090 var_22C = dword ptr -22Ch
.text:0000000000001090 var_228 = qword ptr -228h
.text:0000000000001090 var_220 = qword ptr -220h
.text:0000000000001090 var_218 = qword ptr -218h
.text:0000000000001090 var_210 = qword ptr -210h
.text:0000000000001090 var_205 = byte ptr -205h
.text:0000000000001090 var_204 = dword ptr -204h
.text:0000000000001090 var_200 = qword ptr -200h
.text:0000000000001090 var_1F8 = qword ptr -1F8h
.text:0000000000001090 var_1F0 = qword ptr -1F0h
.text:0000000000001090 var_1E8 = qword ptr -1E8h
.text:0000000000001090 var_1E0 = qword ptr -1E0h
.text:0000000000001090 var_1D1 = byte ptr -1D1h
.text:0000000000001090 var_1D0 = qword ptr -1D0h
.text:0000000000001090 var_1C8 = qword ptr -1C8h
.text:0000000000001090 var_1C0 = qword ptr -1C0h
.text:0000000000001090 var_1B8 = dword ptr -1B8h
.text:0000000000001090 var_1B4 = dword ptr -1B4h
.text:0000000000001090 var_1B0 = byte ptr -1B0h
.text:0000000000001090 var_1A8 = byte ptr -1A8h
.text:0000000000001090 var_190 = byte ptr -190h
.text:0000000000001090 var_188 = byte ptr -188h
.text:0000000000001090 var_180 = byte ptr -180h
.text:0000000000001090 var_178 = byte ptr -178h
.text:0000000000001090 var_170 = xmmword ptr -170h
.text:0000000000001090 var_160 = xmmword ptr -160h
.text:0000000000001090 var_150 = xmmword ptr -150h
.text:0000000000001090 var_140 = qword ptr -140h
.text:0000000000001090 var_138 = qword ptr -138h
.text:0000000000001090 var_130 = dword ptr -130h
.text:0000000000001090 var_128 = byte ptr -128h
.text:0000000000001090 var_F8 = byte ptr -0F8h
.text:0000000000001090 var_C8 = byte ptr -0C8h
.text:0000000000001090 var_98 = byte ptr -98h
.text:0000000000001090 var_68 = byte ptr -68h
.text:0000000000001090 var_38 = byte ptr -38h
.text:0000000000001090 var_8 = qword ptr -8
.text:0000000000001090
.text:0000000000001090 ; __unwind {
.text:0000000000001090 push rbp
.text:0000000000001091 mov rbp, rsp
.text:0000000000001094 sub rsp, 280h
//栈保护
.text:000000000000109B lea rdi, [rbp+var_178]
.text:00000000000010A2 mov rax, fs:28h
.text:00000000000010AB mov [rbp+var_8], rax
.text:00000000000010AF mov [rbp+var_1B8], 0
.text:00000000000010B9 call sub_1570//空函数
//string默认构造
.text:00000000000010BE lea rdi, [rbp+var_38]
.text:00000000000010C2 lea rsi, [rbp+var_178]
.text:00000000000010C9 call sub_1580
.text:00000000000010CE lea rdi, [rbp+var_178]
.text:00000000000010D5 call sub_15C0
// cin>>s; var_38为s
.text:00000000000010DA mov rdi, cs:_ZSt3cin_ptr
.text:00000000000010E1 lea rsi, [rbp+var_38]
.text:00000000000010E5 call sub_15D0
.text:00000000000010EA lea rdi, [rbp+var_180]
.text:00000000000010F1 mov [rbp+var_238], rax
.text:00000000000010F8 call sub_1570
// string s1;//默认构造 var_68为s1
.text:00000000000010FD lea rdi, [rbp+var_68]
.text:0000000000001101 lea rsi, [rbp+var_180]
.text:0000000000001108 call sub_1580
.text:000000000000110D lea rdi, [rbp+var_180]
.text:0000000000001114 call sub_15C0
// string s2(s1);//直接构造
.text:0000000000001119 lea rdi, [rbp+var_98] ; this
.text:0000000000001120 lea rsi, [rbp+var_68] ; std::string *
.text:0000000000001124 call _ZNSsC2ERKSs ; std::string::string(std::string const&)
// string s3=s1;//拷贝初始化 对于一个参的都一样
.text:0000000000001129 lea rdi, [rbp+var_C8] ; this
.text:0000000000001130 lea rsi, [rbp+var_68] ; std::string *
.text:0000000000001134 call _ZNSsC2ERKSs ; std::string::string(std::string const&)
.text:0000000000001139 lea rdi, [rbp+var_188]
.text:0000000000001140 call sub_1570//这个函数是空的
// string s4("1234");//直接构造
.text:0000000000001145 lea rdi, [rbp+var_F8]
.text:000000000000114C lea rsi, a1234 ; "1234"
.text:0000000000001153 lea rdx, [rbp+var_188]
.text:000000000000115A call _ZNSsC2EPKcRKSaIcE ; std::string::string(char const*,std::allocator<char> const&)
.text:000000000000115F lea rdi, [rbp+var_188]
.text:0000000000001166 call sub_15C0//空的
.text:000000000000116B lea rdi, [rbp+var_190]
.text:0000000000001172 call sub_1570
//string s5="1234";//拷贝初始化 对于一个参数的都一样
.text:0000000000001177 lea rdi, [rbp+var_128]
.text:000000000000117E lea rsi, a1234 ; "1234"
.text:0000000000001185 lea rdx, [rbp+var_190]
.text:000000000000118C call _ZNSsC2EPKcRKSaIcE ; std::string::string(char const*,std::allocator<char> const&)
// s5=s1;//赋值
.text:0000000000001191 lea rdi, [rbp+var_190]
.text:0000000000001198 call sub_15C0//空
.text:000000000000119D lea rdi, [rbp+var_128]
.text:00000000000011A4 lea rsi, [rbp+var_68]
.text:00000000000011A8 call sub_1960
//取rdx为s的this-这是获取begin
.text:00000000000011AD lea rdx, [rbp+var_38]
.text:00000000000011B1 mov [rbp+var_1C0], rdx
.text:00000000000011B8 mov rdi, [rbp+var_1C0]
.text:00000000000011BF mov [rbp+var_240], rax
.text:00000000000011C6 call sub_19C0
//存放begin到t t为var_1C8
.text:00000000000011CB mov [rbp+var_1C8], rax
//获取end
.text:00000000000011D2 mov rdi, [rbp+var_1C0]
.text:00000000000011D9 call sub_19E0
.text:00000000000011DE mov [rbp+var_1D0], rax
.text:00000000000011E5
.text:00000000000011E5 loc_11E5: ; CODE XREF: sub_1090+1B3↓j
//比较,相等就跳出
.text:00000000000011E5 mov rax, [rbp+var_1C8]
.text:00000000000011EC cmp rax, [rbp+var_1D0]
.text:00000000000011F3 jz loc_1248
//cout<<t<<std::endl;
.text:00000000000011F9 mov rdi, cs:_ZSt4cout_ptr
.text:0000000000001200 mov rax, [rbp+var_1C8]
//直接解引用t char类型是一个字节8位 这里把它解引用后存到var_1D1,再操控var_1D1。可见这里是做了一次拷贝
.text:0000000000001207 mov cl, [rax]
.text:0000000000001209 mov [rbp+var_1D1], cl
.text:000000000000120F movsx esi, [rbp+var_1D1]
.text:0000000000001216 call sub_1A00
.text:000000000000121B lea rsi, sub_1A50
.text:0000000000001222 mov rdi, rax
.text:0000000000001225 call sub_1A30
.text:000000000000122A mov [rbp+var_248], rax
//t加一
.text:0000000000001231 mov rax, [rbp+var_1C8]
.text:0000000000001238 add rax, 1
.text:000000000000123C mov [rbp+var_1C8], rax
.text:0000000000001243 jmp loc_11E5
.text:0000000000001248 ; ---------------------------------------------------------------------------
.text:0000000000001248
.text:0000000000001248 loc_1248: ; CODE XREF: sub_1090+163↑j
//获取begin end 使用的函数完全一样
.text:0000000000001248 lea rax, [rbp+var_38]
.text:000000000000124C mov [rbp+var_1E0], rax
.text:0000000000001253 mov rdi, [rbp+var_1E0]
.text:000000000000125A call sub_19C0
.text:000000000000125F mov [rbp+var_1E8], rax
.text:0000000000001266 mov rdi, [rbp+var_1E0]
.text:000000000000126D call sub_19E0
.text:0000000000001272 mov [rbp+var_1F0], rax
.text:0000000000001279
.text:0000000000001279 loc_1279: ; CODE XREF: sub_1090+249↓j
//比较
.text:0000000000001279 mov rax, [rbp+var_1E8]
.text:0000000000001280 cmp rax, [rbp+var_1F0]
.text:0000000000001287 jz loc_12DE
.text:000000000000128D mov rdi, cs:_ZSt4cout_ptr
.text:0000000000001294 mov rax, [rbp+var_1E8]
.text:000000000000129B mov [rbp+var_1F8], rax
//t直接就是指向字符的指针 sub_1A00为cin输出单个字符-这里直接解引用了,没有拷贝
.text:00000000000012A2 mov rax, [rbp+var_1F8]
.text:00000000000012A9 movsx esi, byte ptr [rax]
.text:00000000000012AC call sub_1A00
.text:00000000000012B1 lea rsi, sub_1A50
.text:00000000000012B8 mov rdi, rax
.text:00000000000012BB call sub_1A30
.text:00000000000012C0 mov [rbp+var_250], rax
//t++
.text:00000000000012C7 mov rax, [rbp+var_1E8]
.text:00000000000012CE add rax, 1
.text:00000000000012D2 mov [rbp+var_1E8], rax
.text:00000000000012D9 jmp loc_1279
//以上用ida反编译的话结果都一样,t都是char的指针,汇编下是使用的值是直接解t还是解t的拷贝的区别。
.text:00000000000012DE ; ---------------------------------------------------------------------------
.text:00000000000012DE
.text:00000000000012DE loc_12DE: ; CODE XREF: sub_1090+1F7↑j
//auto it=s4.begin() var_200是it
.text:00000000000012DE lea rdi, [rbp+var_F8]
.text:00000000000012E5 call sub_19C0
.text:00000000000012EA mov [rbp+var_200], rax
.text:00000000000012F1
.text:00000000000012F1 loc_12F1: ; CODE XREF: sub_1090+2C9↓j
.text:00000000000012F1 lea rdi, [rbp+var_F8]
.text:00000000000012F8 mov rax, [rbp+var_200]
.text:00000000000012FF mov [rbp+var_258], rax
//获取end
.text:0000000000001306 call sub_19E0
.text:000000000000130B mov rdi, [rbp+var_258]
//比较,不过rdi来源是var_200的备份...
.text:0000000000001312 cmp rdi, rax
.text:0000000000001315 jz loc_135E
//cout<<*it<<std::endl;
.text:000000000000131B mov rdi, cs:_ZSt4cout_ptr
.text:0000000000001322 mov rax, [rbp+var_200]
.text:0000000000001329 movsx esi, byte ptr [rax]
.text:000000000000132C call sub_1A00
.text:0000000000001331 lea rsi, sub_1A50
.text:0000000000001338 mov rdi, rax
.text:000000000000133B call sub_1A30
.text:0000000000001340 mov [rbp+var_260], rax
.text:0000000000001347 mov rax, [rbp+var_200]
.text:000000000000134E add rax, 1
.text:0000000000001352 mov [rbp+var_200], rax
.text:0000000000001359 jmp loc_12F1
.text:000000000000135E ; ---------------------------------------------------------------------------
.text:000000000000135E
.text:000000000000135E loc_135E: ; CODE XREF: sub_1090+285↑j
.text:000000000000135E xor eax, eax
.text:0000000000001360 mov cl, al
// int i1=0;
.text:0000000000001362 mov [rbp+var_204], 0
.text:000000000000136C cmp [rbp+var_204], 1
//var_261是临时表达式值寄存
.text:0000000000001373 mov [rbp+var_261], cl
//相等继续,不等直接跳,先将b1=0了
.text:0000000000001379 jnz loc_138C
.text:000000000000137F mov al, 1
//b1=1
.text:0000000000001381 mov [rbp+var_261], al
.text:0000000000001387 jmp $+5
.text:000000000000138C ; ---------------------------------------------------------------------------
.text:000000000000138C
.text:000000000000138C loc_138C: ; CODE XREF: sub_1090+2E9↑j
.text:000000000000138C ; sub_1090+2F7↑j
//赋值给b1 这里用了and保证0或1
.text:000000000000138C mov al, [rbp+var_261]
.text:0000000000001392 lea rdi, [rbp+var_1B0]
.text:0000000000001399 and al, 1
.text:000000000000139B mov [rbp+var_205], al
.text:00000000000013A1 call sub_1AB0//空
// std::vector<int> vec; var_1A8是this
.text:00000000000013A6 lea rdi, [rbp+var_1A8]
.text:00000000000013AD lea rsi, [rbp+var_1B0]
.text:00000000000013B4 call sub_1AC0
.text:00000000000013B9 lea rdi, [rbp+var_1B0]
.text:00000000000013C0 call sub_1AF0//空
//this和指向3的指针
.text:00000000000013C5 lea rdi, [rbp+var_1A8]
.text:00000000000013CC lea rsi, [rbp+var_1B4]
.text:00000000000013D3 mov [rbp+var_1B4], 3
.text:00000000000013DD call sub_1B00
//rdi指针,esi下标
.text:00000000000013E2 lea rdi, [rbp+var_1A8]
.text:00000000000013E9 xor ecx, ecx
.text:00000000000013EB mov esi, ecx
.text:00000000000013ED call sub_1BF0
//返回的rax是指针,指向下标选择的对象
.text:00000000000013F2 lea rdi, [rbp+var_1A8]
.text:00000000000013F9 mov dword ptr [rax], 1
//auto veci=vec.begin(); var_140是数组的位置
.text:00000000000013FF call sub_1C20
.text:0000000000001404 lea rsi, [rbp+var_140]
.text:000000000000140B mov [rbp+var_210], rax
//{}内的初始化数据放在rodata区。数组栈中低到高
.text:0000000000001412 mov rax, cs:qword_5900 1 2
.text:0000000000001419 mov [rbp+var_140], rax
.text:0000000000001420 mov rax, cs:qword_5908 3 4
.text:0000000000001427 mov [rbp+var_138], rax
.text:000000000000142E mov ecx, cs:dword_5910 5
.text:0000000000001434 mov [rbp+var_130], ecx
//var_218是a,为指针,存储数组的地址
.text:000000000000143A mov [rbp+var_218], rsi
.text:0000000000001441 mov rax, [rbp+var_218]
// i为指针 var_220
.text:0000000000001448 mov [rbp+var_220], rax
.text:000000000000144F mov rax, [rbp+var_218]
.text:0000000000001456 add rax, 14h
//尾后var_228
.text:000000000000145A mov [rbp+var_228], rax
.text:0000000000001461
.text:0000000000001461 loc_1461: ; CODE XREF: sub_1090+42E↓j
//比较,等于就跳
.text:0000000000001461 mov rax, [rbp+var_220]
.text:0000000000001468 cmp rax, [rbp+var_228]
.text:000000000000146F jz loc_14C3
//cout<<i<<" ";
.text:0000000000001475 mov rdi, cs:_ZSt4cout_ptr
.text:000000000000147C mov rax, [rbp+var_220]
.text:0000000000001483 mov ecx, [rax]
.text:0000000000001485 mov [rbp+var_22C], ecx
.text:000000000000148B mov esi, [rbp+var_22C]
.text:0000000000001491 call sub_1C70
.text:0000000000001496 lea rsi, asc_58D5 ; " "
.text:000000000000149D mov rdi, rax
.text:00000000000014A0 call sub_1C40
.text:00000000000014A5 mov [rbp+var_270], rax
//指针++
.text:00000000000014AC mov rax, [rbp+var_220]
.text:00000000000014B3 add rax, 4
.text:00000000000014B7 mov [rbp+var_220], rax
.text:00000000000014BE jmp loc_1461
.text:00000000000014C3 ; ---------------------------------------------------------------------------
.text:00000000000014C3
.text:00000000000014C3 loc_14C3: ; CODE XREF: sub_1090+3DF↑j
//xmm0为128位。16字节,正好是第二维度的4个int
//初始化为0
.text:00000000000014C3 xorps xmm0, xmm0
.text:00000000000014C6 movaps [rbp+var_150], xmm0
.text:00000000000014CD movaps [rbp+var_160], xmm0
.text:00000000000014D4 movaps [rbp+var_170], xmm0
//第三层var_150偏移第4个
.text:00000000000014DB mov dword ptr [rbp+var_150+0Ch], 1
//这里在释放对象!!!!!!
.text:00000000000014E5 lea rdi, [rbp+var_1A8]
.text:00000000000014EC call sub_1CE0
.text:00000000000014F1 lea rdi, [rbp+var_128]
.text:00000000000014F8 call sub_1D60
.text:00000000000014FD lea rdi, [rbp+var_F8]
.text:0000000000001504 call sub_1D60
.text:0000000000001509 lea rdi, [rbp+var_C8]
.text:0000000000001510 call sub_1D60
.text:0000000000001515 lea rdi, [rbp+var_98]
.text:000000000000151C call sub_1D60
.text:0000000000001521 lea rdi, [rbp+var_68]
.text:0000000000001525 call sub_1D60
.text:000000000000152A lea rdi, [rbp+var_38]
.text:000000000000152E call sub_1D60
//检查栈,返回 var_1B8一开始就置0了
.text:0000000000001533 mov eax, [rbp+var_1B8]
.text:0000000000001539 mov rdi, fs:28h
.text:0000000000001542 mov rcx, [rbp+var_8]
.text:0000000000001546 cmp rdi, rcx
.text:0000000000001549 mov [rbp+var_274], eax
.text:000000000000154F jnz loc_1564
.text:0000000000001555 mov eax, [rbp+var_274]
.text:000000000000155B add rsp, 280h
.text:0000000000001562 pop rbp
.text:0000000000001563 retn
.text:0000000000001564 ; ---------------------------------------------------------------------------
.text:0000000000001564
.text:0000000000001564 loc_1564: ; CODE XREF: sub_1090+4BF↑j
.text:0000000000001564 call ___stack_chk_fail
.text:0000000000001564 ; } // starts at 1090
.text:0000000000001564 sub_1090 endp

语句块里的变量也直接定义在函数的栈里了,这部分的访问控制由编译器检查。布尔表达式确实如规定所实现。
注意在函数栈中构造的对象在函数结束时编译器自动添加析构函数调用。此外释放顺序与定义顺序相反。为的是防止使用空指针,依赖者先释放,不影响被依赖者。

对象的构造不论哪种方式都是传入this与参数,实现构造。
对象的操作大多都被定义为函数。传入this。

范围for相当于c式:

1
2
3
4
5
6
7
8
v10 = (char *)sub_19C0(&v30);//取字串头指针
v9 = sub_19E0(&v30);//取尾后指针
while ( v10 != (char *)v9 )
{
v0 = sub_1A00(&std::cout, (unsigned int)*v10);
sub_1A30(v0, sub_1A50);
++v10;
}

范围for调用的函数就是迭代器的函数,也就是说范围for可翻译为:

1
2
3
4
5
for(auto i=vec.begin();i!=vec.end();i++ )
{
auto ls=*i;//是否有这句看加不加&
//todo
}

不过范围for里的end是提前取出之后判断的。普通for是判断时取end。
普通for:

1
2
3
4
for(循环体前;每次求值;每次求值)
{
}

ARM64

指令简记

UXTB 无符号(Unsigned)扩展一个字节(Byte)到 32位

分析

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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
.text:0000000000001318 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:0000000000001318 EXPORT main
.text:0000000000001318 main ; DATA XREF: LOAD:0000000000000560↑o
.text:0000000000001318 ; .got:main_ptr↓o
.text:0000000000001318
.text:0000000000001318 var_2A0 = -0x2A0
.text:0000000000001318 var_29C = -0x29C
.text:0000000000001318 var_298 = -0x298
.text:0000000000001318 var_290 = -0x290
.text:0000000000001318 var_288 = -0x288
.text:0000000000001318 var_27C = -0x27C
.text:0000000000001318 var_278 = -0x278
.text:0000000000001318 var_270 = -0x270
.text:0000000000001318 var_268 = -0x268
.text:0000000000001318 var_260 = -0x260
.text:0000000000001318 var_258 = -0x258
.text:0000000000001318 var_250 = -0x250
.text:0000000000001318 var_248 = -0x248
.text:0000000000001318 var_240 = -0x240
.text:0000000000001318 var_234 = -0x234
.text:0000000000001318 var_230 = -0x230
.text:0000000000001318 var_228 = -0x228
.text:0000000000001318 var_220 = -0x220
.text:0000000000001318 var_218 = -0x218
.text:0000000000001318 var_210 = -0x210
.text:0000000000001318 var_20C = -0x20C
.text:0000000000001318 var_208 = -0x208
.text:0000000000001318 var_200 = -0x200
.text:0000000000001318 var_1F8 = -0x1F8
.text:0000000000001318 var_1F0 = -0x1F0
.text:0000000000001318 var_1E8 = -0x1E8
.text:0000000000001318 var_1DC = -0x1DC
.text:0000000000001318 var_1D8 = -0x1D8
.text:0000000000001318 var_1D0 = -0x1D0
.text:0000000000001318 var_1C8 = -0x1C8
.text:0000000000001318 var_1C0 = -0x1C0
.text:0000000000001318 var_1BC = -0x1BC
.text:0000000000001318 var_1B8 = -0x1B8
.text:0000000000001318 var_1B0 = -0x1B0
.text:0000000000001318 var_198 = -0x198
.text:0000000000001318 var_190 = -0x190
.text:0000000000001318 var_188 = -0x188
.text:0000000000001318 var_180 = -0x180
.text:0000000000001318 var_17C = -0x17C
.text:0000000000001318 var_150 = -0x150
.text:0000000000001318 var_14C = -0x14C
.text:0000000000001318 var_138 = -0x138
.text:0000000000001318 var_108 = -0x108
.text:0000000000001318 var_D8 = -0xD8
.text:0000000000001318 var_A8 = -0xA8
.text:0000000000001318 var_78 = -0x78
.text:0000000000001318 var_48 = -0x48
.text:0000000000001318 var_10 = -0x10
.text:0000000000001318 var_s0 = 0
.text:0000000000001318
.text:0000000000001318 ; __unwind {
//保存栈帧
.text:0000000000001318 STR X28, [SP,#-0x10+var_10]!
.text:000000000000131C STP X29, X30, [SP,#0x10+var_s0]
.text:0000000000001320 ADD X29, SP, #0x10
.text:0000000000001324 SUB SP, SP, #0x290
//栈保护
.text:0000000000001328 ADD X8, SP, #0x2A0+var_240
.text:000000000000132C ADD X0, SP, #0x2A0+var_180
.text:0000000000001330 MRS X9, #3, c13, c0, #2
.text:0000000000001334 LDR X9, [X9,#0x28]
.text:0000000000001338 STR X9, [X8]
.text:000000000000133C STR WZR, [SP,#0x2A0+var_1C0]
.text:0000000000001340 STR X8, [SP,#0x2A0+var_248]
.text:0000000000001344 BL sub_16F0
// var_48是s的this
.text:0000000000001348 SUB X0, X29, #-var_48
.text:000000000000134C ADD X1, SP, #0x2A0+var_180
.text:0000000000001350 BL sub_1700
.text:0000000000001354 ADD X0, SP, #0x2A0+var_180
.text:0000000000001358 BL sub_1748 //空
// cin>>s;
.text:000000000000135C ADRP X8, #_ZSt3cin_ptr@PAGE
.text:0000000000001360 LDR X0, [X8,#_ZSt3cin_ptr@PAGEOFF]
.text:0000000000001364 SUB X1, X29, #-var_48
.text:0000000000001368 BL sub_1758
.text:000000000000136C ADD X8, SP, #0x2A0+var_188
.text:0000000000001370 STR X0, [SP,#0x2A0+var_250]
.text:0000000000001374 MOV X0, X8
.text:0000000000001378 BL sub_16F0//空
//string s1;
.text:000000000000137C SUB X0, X29, #-var_78
.text:0000000000001380 ADD X1, SP, #0x2A0+var_188
.text:0000000000001384 BL sub_1700
.text:0000000000001388 ADD X0, SP, #0x2A0+var_188
.text:000000000000138C BL sub_1748
// string s2(s1);//直接构造
.text:0000000000001390 SUB X0, X29, #-var_A8 ; this
.text:0000000000001394 SUB X1, X29, #-var_78 ; std::string *
.text:0000000000001398 BL _ZNSsC2ERKSs ; std::string::string(std::string const&)
// string s3=s1;//拷贝初始化
.text:000000000000139C SUB X0, X29, #-var_D8 ; this
.text:00000000000013A0 SUB X1, X29, #-var_78 ; std::string *
.text:00000000000013A4 BL _ZNSsC2ERKSs ; std::string::string(std::string const&)
.text:00000000000013A8 ADD X0, SP, #0x2A0+var_190
.text:00000000000013AC BL sub_16F0
// string s4("1234");//直接构造
.text:00000000000013B0 ADD X0, SP, #0x2A0+var_108
.text:00000000000013B4 ADRP X8, #a1234@PAGE ; "1234"
.text:00000000000013B8 ADD X1, X8, #a1234@PAGEOFF ; "1234"
.text:00000000000013BC ADD X2, SP, #0x2A0+var_190
.text:00000000000013C0 BL _ZNSsC2EPKcRKSaIcE ; std::string::string(char const*,std::allocator<char> const&)
.text:00000000000013C4 ADD X0, SP, #0x2A0+var_190
.text:00000000000013C8 BL sub_1748
.text:00000000000013CC ADD X0, SP, #0x2A0+var_198
.text:00000000000013D0 BL sub_16F0
// string s5="1234";//拷贝初始化
.text:00000000000013D4 ADD X0, SP, #0x2A0+var_138
.text:00000000000013D8 ADRP X8, #a1234@PAGE ; "1234"
.text:00000000000013DC ADD X1, X8, #a1234@PAGEOFF ; "1234"
.text:00000000000013E0 ADD X2, SP, #0x2A0+var_198
.text:00000000000013E4 BL _ZNSsC2EPKcRKSaIcE ; std::string::string(char const*,std::allocator<char> const&)
.text:00000000000013E8 ADD X0, SP, #0x2A0+var_198
.text:00000000000013EC BL sub_1748
// s5=s1;//赋值
.text:00000000000013F0 ADD X0, SP, #0x2A0+var_138
.text:00000000000013F4 SUB X1, X29, #-var_78
.text:00000000000013F8 BL sub_1AD4
//s的this-获取begin
.text:00000000000013FC SUB X8, X29, #-var_48
.text:0000000000001400 STR X8, [SP,#0x2A0+var_1C8]
.text:0000000000001404 LDR X8, [SP,#0x2A0+var_1C8]
.text:0000000000001408 STR X0, [SP,#0x2A0+var_258]
.text:000000000000140C MOV X0, X8
.text:0000000000001410 BL sub_1B44
//获取end
.text:0000000000001414 STR X0, [SP,#0x2A0+var_1D0]
.text:0000000000001418 LDR X0, [SP,#0x2A0+var_1C8]
.text:000000000000141C BL sub_1B68
.text:0000000000001420 STR X0, [SP,#0x2A0+var_1D8]
.text:0000000000001424
.text:0000000000001424 loc_1424 ; CODE XREF: main+158↓j
//比较
.text:0000000000001424 LDR X8, [SP,#0x2A0+var_1D0]
.text:0000000000001428 LDR X9, [SP,#0x2A0+var_1D8]
.text:000000000000142C CMP X8, X9
.text:0000000000001430 B.EQ loc_1474 //相等时跳
//cout<<t<<std::endl;
.text:0000000000001434 ADRP X8, #_ZSt4cout_ptr@PAGE
.text:0000000000001438 LDR X0, [X8,#_ZSt4cout_ptr@PAGEOFF]
.text:000000000000143C LDR X8, [SP,#0x2A0+var_1D0]
.text:0000000000001440 LDRB W9, [X8]
//备份了一份*it
.text:0000000000001444 STRB W9, [SP,#0x2A0+var_1DC]
.text:0000000000001448 LDRB W9, [SP,#0x2A0+var_1DC]
.text:000000000000144C UXTB W1, W9
.text:0000000000001450 BL sub_1B8C
.text:0000000000001454 ADRP X8, #sub_1BEC@PAGE
.text:0000000000001458 ADD X1, X8, #sub_1BEC@PAGEOFF
.text:000000000000145C BL sub_1BC0
.text:0000000000001460 STR X0, [SP,#0x2A0+var_260]
.text:0000000000001464 LDR X8, [SP,#0x2A0+var_1D0]
.text:0000000000001468 ADD X8, X8, #1
.text:000000000000146C STR X8, [SP,#0x2A0+var_1D0]
.text:0000000000001470 B loc_1424
.text:0000000000001474 ; ---------------------------------------------------------------------------
.text:0000000000001474
.text:0000000000001474 loc_1474 ; CODE XREF: main+118↑j
//取begin与end
.text:0000000000001474 SUB X8, X29, #-var_48
.text:0000000000001478 STR X8, [SP,#0x2A0+var_1E8]
.text:000000000000147C LDR X0, [SP,#0x2A0+var_1E8]
.text:0000000000001480 BL sub_1B44
.text:0000000000001484 STR X0, [SP,#0x2A0+var_1F0]
.text:0000000000001488 LDR X0, [SP,#0x2A0+var_1E8]
.text:000000000000148C BL sub_1B68
.text:0000000000001490 STR X0, [SP,#0x2A0+var_1F8]
.text:0000000000001494
//比较
.text:0000000000001494 loc_1494 ; CODE XREF: main+1C8↓j
.text:0000000000001494 LDR X8, [SP,#0x2A0+var_1F0]
.text:0000000000001498 LDR X9, [SP,#0x2A0+var_1F8]
.text:000000000000149C CMP X8, X9
.text:00000000000014A0 B.EQ loc_14E4
//for体
.text:00000000000014A4 ADRP X8, #_ZSt4cout_ptr@PAGE
.text:00000000000014A8 LDR X0, [X8,#_ZSt4cout_ptr@PAGEOFF]
//直接解it
.text:00000000000014AC LDR X8, [SP,#0x2A0+var_1F0]
.text:00000000000014B0 STR X8, [SP,#0x2A0+var_200]
.text:00000000000014B4 LDR X8, [SP,#0x2A0+var_200]
.text:00000000000014B8 LDRB W9, [X8]
.text:00000000000014BC UXTB W1, W9
.text:00000000000014C0 BL sub_1B8C
.text:00000000000014C4 ADRP X8, #sub_1BEC@PAGE
.text:00000000000014C8 ADD X1, X8, #sub_1BEC@PAGEOFF
.text:00000000000014CC BL sub_1BC0
.text:00000000000014D0 STR X0, [SP,#0x2A0+var_268]
.text:00000000000014D4 LDR X8, [SP,#0x2A0+var_1F0]
.text:00000000000014D8 ADD X8, X8, #1
.text:00000000000014DC STR X8, [SP,#0x2A0+var_1F0]
.text:00000000000014E0 B loc_1494
.text:00000000000014E4 ; ---------------------------------------------------------------------------
.text:00000000000014E4
.text:00000000000014E4 loc_14E4 ; CODE XREF: main+188↑j
//auto it=s4.begin()
.text:00000000000014E4 ADD X0, SP, #0x2A0+var_108
.text:00000000000014E8 BL sub_1B44
.text:00000000000014EC STR X0, [SP,#0x2A0+var_208]
.text:00000000000014F0
.text:00000000000014F0 loc_14F0 ; CODE XREF: main+228↓j
//取end,判断
.text:00000000000014F0 ADD X0, SP, #0x2A0+var_108
.text:00000000000014F4 LDR X8, [SP,#0x2A0+var_208]
.text:00000000000014F8 STR X8, [SP,#0x2A0+var_270]
.text:00000000000014FC BL sub_1B68
.text:0000000000001500 LDR X8, [SP,#0x2A0+var_270]
.text:0000000000001504 CMP X8, X0
.text:0000000000001508 B.EQ loc_1544
//for体
.text:000000000000150C ADRP X8, #_ZSt4cout_ptr@PAGE
.text:0000000000001510 LDR X0, [X8,#_ZSt4cout_ptr@PAGEOFF]
.text:0000000000001514 LDR X8, [SP,#0x2A0+var_208]
.text:0000000000001518 LDRB W9, [X8]
.text:000000000000151C UXTB W1, W9
.text:0000000000001520 BL sub_1B8C
.text:0000000000001524 ADRP X8, #sub_1BEC@PAGE
.text:0000000000001528 ADD X1, X8, #sub_1BEC@PAGEOFF
.text:000000000000152C BL sub_1BC0
.text:0000000000001530 STR X0, [SP,#0x2A0+var_278]
.text:0000000000001534 LDR X8, [SP,#0x2A0+var_208]
.text:0000000000001538 ADD X8, X8, #1
.text:000000000000153C STR X8, [SP,#0x2A0+var_208]
.text:0000000000001540 B loc_14F0
.text:0000000000001544 ; ---------------------------------------------------------------------------
.text:0000000000001544
.text:0000000000001544 loc_1544 ; CODE XREF: main+1F0↑j
//int i1=0;
.text:0000000000001544 MOV W8, WZR
.text:0000000000001548 STR WZR, [SP,#0x2A0+var_20C]
// bool b1=i1==1&&true; var_27C是b1
.text:000000000000154C LDR W9, [SP,#0x2A0+var_20C]
.text:0000000000001550 CMP W9, #1
.text:0000000000001554 STR W8, [SP,#0x2A0+var_27C]
.text:0000000000001558 B.NE loc_1568
.text:000000000000155C MOV W8, #1
.text:0000000000001560 STR W8, [SP,#0x2A0+var_27C]
.text:0000000000001564 B loc_1568
.text:0000000000001568 ; ---------------------------------------------------------------------------
.text:0000000000001568
.text:0000000000001568 loc_1568 ; CODE XREF: main+240↑j
.text:0000000000001568 ; main+24C↑j
//将b1置1/0
.text:0000000000001568 LDR W8, [SP,#0x2A0+var_27C]
.text:000000000000156C ADD X0, SP, #0x2A0+var_1B8
.text:0000000000001570 AND W8, W8, #1
.text:0000000000001574 STRB W8, [SP,#0x2A0+var_210]
.text:0000000000001578 BL sub_1C60
// std::vector<int> vec; var_1B0为vec的this
.text:000000000000157C ADD X0, SP, #0x2A0+var_1B0
.text:0000000000001580 ADD X1, SP, #0x2A0+var_1B8
.text:0000000000001584 BL sub_1C70
.text:0000000000001588 ADD X0, SP, #0x2A0+var_1B8
.text:000000000000158C BL sub_1C9C//空
// vec.push_back(3);传入的是指向3的指针
.text:0000000000001590 ADD X0, SP, #0x2A0+var_1B0
.text:0000000000001594 ADD X1, SP, #0x2A0+var_1BC
.text:0000000000001598 MOV W8, #3
.text:000000000000159C STR W8, [SP,#0x2A0+var_1BC]
.text:00000000000015A0 BL sub_1CAC
//获取0号
.text:00000000000015A4 ADD X0, SP, #0x2A0+var_1B0
.text:00000000000015A8 MOV X1, XZR
.text:00000000000015AC BL sub_1D98
// vec[0]=1;
.text:00000000000015B0 ADD X1, SP, #0x2A0+var_1B0
.text:00000000000015B4 MOV W8, #1
.text:00000000000015B8 STR W8, [X0]
// auto veci=vec.begin();
.text:00000000000015BC MOV X0, X1
.text:00000000000015C0 BL sub_1DD0
// int a[5]={1,2,3,4,5}; var_14C是数组地址,这里直接用了memcpy。var_288是指针,存var_14C
.text:00000000000015C4 ADD X1, SP, #0x2A0+var_14C
.text:00000000000015C8 ADRP X30, #unk_5A4C@PAGE
.text:00000000000015CC ADD X30, X30, #unk_5A4C@PAGEOFF
.text:00000000000015D0 MOV X2, #0x14
.text:00000000000015D4 STR X0, [SP,#0x2A0+var_218]
.text:00000000000015D8 MOV X0, X1
.text:00000000000015DC STR X1, [SP,#0x2A0+var_288]
.text:00000000000015E0 MOV X1, X30
.text:00000000000015E4 BL .memcpy
.text:00000000000015E8 LDR X0, [SP,#0x2A0+var_288]
.text:00000000000015EC STR X0, [SP,#0x2A0+var_220]
//初始化i
.text:00000000000015F0 LDR X1, [SP,#0x2A0+var_220]
.text:00000000000015F4 STR X1, [SP,#0x2A0+var_228]
//尾后
.text:00000000000015F8 LDR X1, [SP,#0x2A0+var_220]
.text:00000000000015FC ADD X1, X1, #0x14
.text:0000000000001600 STR X1, [SP,#0x2A0+var_230]
.text:0000000000001604
.text:0000000000001604 loc_1604 ; CODE XREF: main+334↓j
//比较
.text:0000000000001604 LDR X8, [SP,#0x2A0+var_228]
.text:0000000000001608 LDR X9, [SP,#0x2A0+var_230]
.text:000000000000160C CMP X8, X9
.text:0000000000001610 B.EQ loc_1650
.text:0000000000001614 ADRP X8, #_ZSt4cout_ptr@PAGE
.text:0000000000001618 LDR X0, [X8,#_ZSt4cout_ptr@PAGEOFF]
.text:000000000000161C LDR X8, [SP,#0x2A0+var_228]
.text:0000000000001620 LDR W9, [X8]
.text:0000000000001624 STR W9, [SP,#0x2A0+var_234]
.text:0000000000001628 LDR W1, [SP,#0x2A0+var_234]
.text:000000000000162C BL sub_1E18
.text:0000000000001630 ADRP X8, #asc_5A25@PAGE ; " "
.text:0000000000001634 ADD X1, X8, #asc_5A25@PAGEOFF ; " "
.text:0000000000001638 BL sub_1DE8
.text:000000000000163C STR X0, [SP,#0x2A0+var_290]
.text:0000000000001640 LDR X8, [SP,#0x2A0+var_228]
.text:0000000000001644 ADD X8, X8, #4
.text:0000000000001648 STR X8, [SP,#0x2A0+var_228]
.text:000000000000164C B loc_1604
.text:0000000000001650 ; ---------------------------------------------------------------------------
.text:0000000000001650
.text:0000000000001650 loc_1650 ; CODE XREF: main+2F8↑j
//
.text:0000000000001650 ADD X0, SP, #0x2A0+var_1B0
.text:0000000000001654 MOV W8, #1
.text:0000000000001658 MOV W9, WZR
.text:000000000000165C MOV X2, #0x30
.text:0000000000001660 ADD X10, SP, #0x2A0+var_17C
.text:0000000000001664 STR X0, [SP,#0x2A0+var_298]
// int a2[3][4]={0}; var_17C是a2地址
.text:0000000000001668 MOV X0, X10
.text:000000000000166C UXTB W1, W9
.text:0000000000001670 STR W8, [SP,#0x2A0+var_29C]
.text:0000000000001674 BL .memset
// a2[2][3]=1;17C-150=44个字节 8+3=11 正确
.text:0000000000001678 LDR W8, [SP,#0x2A0+var_29C]
.text:000000000000167C STR W8, [SP,#0x2A0+var_150]
//析构函数
.text:0000000000001680 LDR X0, [SP,#0x2A0+var_298]
.text:0000000000001684 BL sub_1E90
.text:0000000000001688 ADD X0, SP, #0x2A0+var_138
.text:000000000000168C BL sub_1F0C
.text:0000000000001690 ADD X0, SP, #0x2A0+var_108
.text:0000000000001694 BL sub_1F0C
.text:0000000000001698 SUB X0, X29, #-var_D8
.text:000000000000169C BL sub_1F0C
.text:00000000000016A0 SUB X0, X29, #-var_A8
.text:00000000000016A4 BL sub_1F0C
.text:00000000000016A8 SUB X0, X29, #-var_78
.text:00000000000016AC BL sub_1F0C
.text:00000000000016B0 SUB X0, X29, #-var_48
.text:00000000000016B4 BL sub_1F0C
//栈检查,返回结果
.text:00000000000016B8 LDR W0, [SP,#0x2A0+var_1C0]
.text:00000000000016BC MRS X10, #3, c13, c0, #2
.text:00000000000016C0 LDR X10, [X10,#0x28]
.text:00000000000016C4 LDR X2, [SP,#0x2A0+var_248]
.text:00000000000016C8 LDR X30, [X2]
.text:00000000000016CC CMP X10, X30
.text:00000000000016D0 STR W0, [SP,#0x2A0+var_2A0]
.text:00000000000016D4 B.NE loc_16EC
.text:00000000000016D8 LDR W0, [SP,#0x2A0+var_2A0]
.text:00000000000016DC ADD SP, SP, #0x290
.text:00000000000016E0 LDP X29, X30, [SP,#0x10+var_s0]
.text:00000000000016E4 LDR X28, [SP+0x10+var_10],#0x20
.text:00000000000016E8 RET
.text:00000000000016EC ; ---------------------------------------------------------------------------
.text:00000000000016EC
.text:00000000000016EC loc_16EC ; CODE XREF: main+3BC↑j
.text:00000000000016EC BL .__stack_chk_fail
.text:00000000000016EC ; } // starts at 1318
.text:00000000000016EC ; End of function main

这里看下:

1
2
3
4
5
6
7
8
9
10
// int a[5]={1,2,3,4,5}; var_14C是数组地址,这里直接用了memcpy。var_288是指针,存var_14C
.text:00000000000015C4 ADD X1, SP, #0x2A0+var_14C
.text:00000000000015C8 ADRP X30, #unk_5A4C@PAGE
.text:00000000000015CC ADD X30, X30, #unk_5A4C@PAGEOFF
.text:00000000000015D0 MOV X2, #0x14
.text:00000000000015D4 STR X0, [SP,#0x2A0+var_218]
.text:00000000000015D8 MOV X0, X1
.text:00000000000015DC STR X1, [SP,#0x2A0+var_288]
.text:00000000000015E0 MOV X1, X30
.text:00000000000015E4 BL .memcpy

汇编的表示只有值,传入的变量实质是传入变量的值。这里数组的地址是var_14C但a的地址是var_288也就是说a是一个指针,指针存有var_14C。当调用mencpy函数时,传入的是var_14C,也就是对象的值。

一定明确:汇编下只有地址:值。 寄存器:值 一切语法的表示最后都是这个样子。过程间传递的都是值。而且都是拷贝到指定寄存器传递的。指针就是一个值是地址的对象。