phase_6

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
;phase_6开始
0x00000000004010f4 <+0>: push %r14
0x00000000004010f6 <+2>: push %r13
0x00000000004010f8 <+4>: push %r12
0x00000000004010fa <+6>: push %rbp
0x00000000004010fb <+7>: push %rbx
0x00000000004010fc <+8>: sub $0x50,%rsp ;分配50个字节的空间

0x0000000000401100 <+12>: mov %rsp,%r13
0x0000000000401103 <+15>: mov %rsp,%rsi
0x0000000000401106 <+18>: callq 0x40145c <read_six_numbers> ;读入6个数,读入的6个数从%rsp开始存,依次存在%rsp, %rsp+4, ..., %rsp+20

0x000000000040110b <+23>: mov %rsp,%r14 ;将rsp的地址传递给r14
0x000000000040110e <+26>: mov $0x0,%r12d ;将r12低32位赋值为0

;loop1 begin (for r12d: 0-5) ;第一层循环
0x0000000000401114 <+32>: mov %r13,%rbp
0x0000000000401117 <+35>: mov 0x0(%r13),%eax ;将r13的值+0送到eax
0x000000000040111b <+39>: sub $0x1,%eax ;eax-=1
0x000000000040111e <+42>: cmp $0x5,%eax
0x0000000000401121 <+45>: jbe 0x401128 <phase_6+52> ;上面两行相当于eax-1<=5,即eax<=6时跳转到+52,否则explode_bomb

0x0000000000401123 <+47>: callq 0x40143a <explode_bomb> ;mission failed

0x0000000000401128 <+52>: add $0x1,%r12d ;r12d++
0x000000000040112c <+56>: cmp $0x6,%r12d
0x0000000000401130 <+60>: je 0x401153 <phase_6+95> ;如果r12d==6,说明已经比较完了,那么跳转到+95(跳出循环)

0x0000000000401132 <+62>: mov %r12d,%ebx ;将r12低32位送到ebx

;loop2_in_1 begin (for ebx: r12d-5) ;开始第二层循环
0x0000000000401135 <+65>: movslq %ebx,%rax
0x0000000000401138 <+68>: mov (%rsp,%rax,4),%eax
0x000000000040113b <+71>: cmp %eax,0x0(%rbp) ;比较第一层循环枚举到的数(0x0(%rbp))和当前枚举到的数是否相等
0x000000000040113e <+74>: jne 0x401145 <phase_6+81> ;不相等则跳转到+81继续执行,相等则explode_bomb

0x0000000000401140 <+76>: callq 0x40143a <explode_bomb> ;mission failed

0x0000000000401145 <+81>: add $0x1,%ebx ;ebx++
0x0000000000401148 <+84>: cmp $0x5,%ebx ;
0x000000000040114b <+87>: jle 0x401135 <phase_6+65> ;上面两行相当于如果ebx+1<=5,则跳转到+65(第二层循环起点)
;loop2_in_1 end.

0x000000000040114d <+89>: add $0x4,%r13
0x0000000000401151 <+93>: jmp 0x401114 <phase_6+32> ;进入下一次循环
;loop1 end. ;根据以上可以得出这两层循环是在判断输入的6个数都是小于等于6的,并且互不相等,否则便会引爆炸弹。

0x0000000000401153 <+95>: lea 0x18(%rsp),%rsi ;将地址传给rsi,由+118可知这是循环结束的条件(0x18(%rsp)为*(rsp+24),注意区分十进制和十六进制)
0x0000000000401158 <+100>: mov %r14,%rax ;将r14的地址传给rax,由前面我们知道r14的地址存的是rsp的地址,即为那6个数的首地址
0x000000000040115b <+103>: mov $0x7,%ecx ;将ecx赋值为7

;loop3 begin(for six values in rsp)
0x0000000000401160 <+108>: mov %ecx,%edx ;将ecx的值送到edx中(值为7)
0x0000000000401162 <+110>: sub (%rax),%edx ;把edx-*rax的值送到edx中,即edx-=*rax

0x0000000000401164 <+112>: mov %edx,(%rax) ;把edx的值送到*rax中,结合上两句,一次循环的操作*rax=7-*rax
0x0000000000401166 <+114>: add $0x4,%rax ;rax+4,即访问下一个地址
0x000000000040116a <+118>: cmp %rsi,%rax ;判断是否循环到结束条件
0x000000000040116d <+121>: jne 0x401160 <phase_6+108> ;如果没有继续循环loop3
;loop3 end. ;根据loop3可以得出将输入的6个数中每一个数x变成7-x

0x000000000040116f <+123>: mov $0x0,%esi ;esi=0
0x0000000000401174 <+128>: jmp 0x401197 <phase_6+163> ;直接跳转到+163

;loop4 begin

;loop5 begin ;嵌套在loop4里面
0x0000000000401176 <+130>: mov 0x8(%rdx),%rdx ;访问下一个地址(链表的下一个元素)

0x000000000040117a <+134>: add $0x1,%eax ;eax+=1
0x000000000040117d <+137>: cmp %ecx,%eax ;比较ecx和eax
0x000000000040117f <+139>: jne 0x401176 <phase_6+130>
;loop5 end.

0x0000000000401181 <+141>: jmp 0x401188 <phase_6+148> ;注意这里是直接跳转到+148,不执行+143

0x0000000000401183 <+143>: mov $0x6032d0,%edx
;使用"p/s *0x6032d0 @24"查看
;*0x6032d0: {332, 1, 6304480, 0, 168, 2, 6304496, 0, 924, 3, 6304512, 0, 691, 4, 6304528, 0, 477, 5, 6304544, 0, 443, 6, 0, 0}
;可以得到这个链表一共有6个元素,每个元素有4个字节,第三个字节为下一个元素的地址,第四个字节为0,前两个暂不清楚

0x0000000000401188 <+148>: mov %rdx,0x20(%rsp,%rsi,2)

0x000000000040118d <+153>: add $0x4,%rsi ;访问下一个地址
0x0000000000401191 <+157>: cmp $0x18,%rsi ;如果到最后一个地址则结束(rsi==24,注意区分十进制和十六进制)
0x0000000000401195 <+161>: je 0x4011ab <phase_6+183> ;如果相等就结束循环

0x0000000000401197 <+163>: mov (%rsp,%rsi,1),%ecx ;不满足循环结束条件/从+128跳转过来,作为第一次循环的入口
0x000000000040119a <+166>: cmp $0x1,%ecx
0x000000000040119d <+169>: jle 0x401183 <phase_6+143> ;ecx<=1则跳转到+143

0x000000000040119f <+171>: mov $0x1,%eax ;赋初值eax=1
0x00000000004011a4 <+176>: mov $0x6032d0,%edx ;传入链表的首地址到edx
0x00000000004011a9 <+181>: jmp 0x401176 <phase_6+130> ;开始循环
;loop4 end.

0x00000000004011ab <+183>: mov 0x20(%rsp),%rbx ;rbx=*(rsp+32),则rbx存的为排序关键数
0x00000000004011b0 <+188>: lea 0x28(%rsp),%rax ;将*(rsp+40)的地址送到rax
0x00000000004011b5 <+193>: lea 0x50(%rsp),%rsi ;将*(rps+80)的地址送到rsi
0x00000000004011ba <+198>: mov %rbx,%rcx ;将rbx送到rcx,即rcx=rbx=*(rsp+32)

;loop begin for(rax 40-80)
0x00000000004011bd <+201>: mov (%rax),%rdx ;rdx=*rax
0x00000000004011c0 <+204>: mov %rdx,0x8(%rcx) ;*(rcx+8)=rdx
0x00000000004011c4 <+208>: add $0x8,%rax ;rax+=8

0x00000000004011c8 <+212>: cmp %rsi,%rax ;比较rsi和rax
0x00000000004011cb <+215>: je 0x4011d2 <phase_6+222> ;当rax==rsi时跳转到+222,即结束循环

0x00000000004011cd <+217>: mov %rdx,%rcx ;rcx=rdx=*(rcx+8)
0x00000000004011d0 <+220>: jmp 0x4011bd <phase_6+201> ;继续循环
;loop end.

0x00000000004011d2 <+222>: movq $0x0,0x8(%rdx)

0x00000000004011da <+230>: mov $0x5,%ebp ;赋值,数据寄存器ebp=5

;loop begin
0x00000000004011df <+235>: mov 0x8(%rbx),%rax ;rax=*(rbx+8)
0x00000000004011e3 <+239>: mov (%rax),%eax ;eax=*rax=*(rbx+8)
0x00000000004011e5 <+241>: cmp %eax,(%rbx)
0x00000000004011e7 <+243>: jge 0x4011ee <phase_6+250> ;如果*rbx>eax=*(rbx+8),即前一个数必须大于后一个数,则跳转到+250,否则explode_bomb

0x00000000004011e9 <+245>: callq 0x40143a <explode_bomb>

0x00000000004011ee <+250>: mov 0x8(%rbx),%rbx ;将*(rbx+8)送到rbx,为下一次循环做准备(准备比较下一个数和下下个数)
0x00000000004011f2 <+254>: sub $0x1,%ebp ;ebp-=1
0x00000000004011f5 <+257>: jne 0x4011df <phase_6+235> ;ebp不为0则继续循环
;loop end. ;这个循环判断整个序列是否按大小降序排列,如果不是则执行explode_bomb

;phase_6结束
0x00000000004011f7 <+259>: add $0x50,%rsp
0x00000000004011fb <+263>: pop %rbx
0x00000000004011fc <+264>: pop %rbp
0x00000000004011fd <+265>: pop %r12
0x00000000004011ff <+267>: pop %r13
0x0000000000401201 <+269>: pop %r14
0x0000000000401203 <+271>: retq