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
|