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
| 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 0x0000000000401100 <+12>: mov %rsp,%r13 #r13 = rsp 0x0000000000401103 <+15>: mov %rsp,%rsi #rsi = rsp 0x0000000000401106 <+18>: callq 0x40145c <read_six_numbers> 0x000000000040110b <+23>: mov %rsp,%r14 #r14 = rsp 0x000000000040110e <+26>: mov $0x0,%r12d #r12d = 0 ------------------------------------------------------------------------------------ 这里可以看出来应该是让我们读入6个数字 ------------------------------------------------------------------------------------part 1 0x0000000000401114 <+32>: mov %r13,%rbp #rbp = r13 = rsp 0x0000000000401117 <+35>: mov 0x0(%r13),%eax #eax = M[r13 + 0]; 0x000000000040111b <+39>: sub $0x1,%eax #eax -= 1 0x000000000040111e <+42>: cmp $0x5,%eax 0x0000000000401121 <+45>: jbe 0x401128 <phase_6+52> #if eax <= 5 to <+52> 0x0000000000401123 <+47>: callq 0x40143a <explode_bomb> #else bomb! 0x0000000000401128 <+52>: add $0x1,%r12d #r12d += 1 0x000000000040112c <+56>: cmp $0x6,%r12d 0x0000000000401130 <+60>: je 0x401153 <phase_6+95> #if r12d = 6 0x0000000000401132 <+62>: mov %r12d,%ebx #ebx = r12d 0x0000000000401135 <+65>: movslq %ebx,%rax #rax = ebx 0x0000000000401138 <+68>: mov (%rsp,%rax,4),%eax #eax = M[rsp + rax * 4] 0x000000000040113b <+71>: cmp %eax,0x0(%rbp) 0x000000000040113e <+74>: jne 0x401145 <phase_6+81>#if M[rbp] != eax go to <+81> 0x0000000000401140 <+76>: callq 0x40143a <explode_bomb> #else bomb! 0x0000000000401145 <+81>: add $0x1,%ebx #ebx++ 0x0000000000401148 <+84>: cmp $0x5,%ebx 0x000000000040114b <+87>: jle 0x401135 <phase_6+65> #if ebx <= 5 go to <+65> 0x000000000040114d <+89>: add $0x4,%r13 #r13+=4 0x0000000000401151 <+93>: jmp 0x401114 <phase_6+32> #go to <+32> ------------------------------------------------------------------------------------ 写成c语言: for (int i = 1; i <= 6; i++) { if (nums[i] > 6) bomb(); for (int j = 1; j <= 6; j++) { if (nums[i] == nums[j]) bomb(); } } 应该是让我们输入的数字在1-6的范围内且不重复 ------------------------------------------------------------------------------------part 2 0x0000000000401153 <+95>: lea 0x18(%rsp),%rsi #rsi = R[rsp] + 24 0x0000000000401158 <+100>: mov %r14,%rax #rax = r14:rsp 0x000000000040115b <+103>: mov $0x7,%ecx #ecx = 7 0x0000000000401160 <+108>: mov %ecx,%edx 0x0000000000401162 <+110>: sub (%rax),%edx #edx = 7 - M[rsp] 0x0000000000401164 <+112>: mov %edx,(%rax) #M[rsp] = edx 0x0000000000401166 <+114>: add $0x4,%rax #rax += 4 : rsp上移4 0x000000000040116a <+118>: cmp %rsi,%rax 0x000000000040116d <+121>: jne 0x401160 <phase_6+108> #if rsi != rax goto <+108> ------------------------------------------------------------------------------------ 写成c语言 for (int i = 1; i <= 6; i++) { nums[i] = 7 - nums[i]; } 应该是把我们输入的数字取了一个相反的顺序,比如原来是1,2,3,4,5,6,现在变成了6,5,4,3,2,1 ------------------------------------------------------------------------------------part 3 0x000000000040116f <+123>: mov $0x0,%esi #esi = 0 0x0000000000401174 <+128>: jmp 0x401197 <phase_6+163> 0x0000000000401176 <+130>: mov 0x8(%rdx),%rdx # rdx = rdx + 8 ->(p = p.next,后移指针) 0x000000000040117a <+134>: add $0x1,%eax #eax = 2 0x000000000040117d <+137>: cmp %ecx,%eax 0x000000000040117f <+139>: jne 0x401176 <phase_6+130> 0x0000000000401181 <+141>: jmp 0x401188 <phase_6+148> 0x0000000000401183 <+143>: mov $0x6032d0,%edx #edx = 0x6032d0 0x0000000000401188 <+148>: mov %rdx,0x20(%rsp,%rsi,2) #M[rsp + 0 * 2 + 0x20] = rdx = 0x6032d0 0x000000000040118d <+153>: add $0x4,%rsi #rsi += 4 0x0000000000401191 <+157>: cmp $0x18,%rsi 0x0000000000401195 <+161>: je 0x4011ab <phase_6+183> #if rsi == 0x18(24) to <+183> 0x0000000000401197 <+163>: mov (%rsp,%rsi,1),%ecx #ecx = M[rsp + rsi] 0x000000000040119a <+166>: cmp $0x1,%ecx 0x000000000040119d <+169>: jle 0x401183 <phase_6+143> #if ecx <= 1 to <+143> 0x000000000040119f <+171>: mov $0x1,%eax #eax = 1 0x00000000004011a4 <+176>: mov $0x6032d0,%edx #edx = 0x6032d0:0x6032d0为指向node1的指针位置 0x00000000004011a9 <+181>: jmp 0x401176 <phase_6+130> ------------------------------------------------------------------------------------ 先把0x6032d0之后的数据显示出来 0x6032d0 <node1>: 0x0000014c 0x00000001 0x006032e0 0x00000000 332 0x6032e0 <node2>: 0x000000a8 0x00000002 0x006032f0 0x00000000 168 0x6032f0 <node3>: 0x0000039c 0x00000003 0x00603300 0x00000000 924 0x603300 <node4>: 0x000002b3 0x00000004 0x00603310 0x00000000 691 0x603310 <node5>: 0x000001dd 0x00000005 0x00603320 0x00000000 477 0x603320 <node6>: 0x000001bb 0x00000006 0x00000000 0x00000000 443 此时我有点懵逼,这是个啥,不过根据查询网上的信息,得知这是个链表,结构如下 struct node { int val;(4字节) int serialNumber;(4字节) struct node *next;(8字节) } 然后查询跑完此段后的rsp + 20后面的数据 (gdb) x/12x ($rsp + 0x20) 0x7fffffffde70: 0x006032f0 0x00000000 0x00603300 0x00000000 0x7fffffffde80: 0x00603310 0x00000000 0x00603320 0x00000000 0x7fffffffde90: 0x006032d0 0x00000000 0x006032e0 0x00000000 可以发现程序把每个结点的位置放到了此处,应该是根据part2部分得出的反转后的顺序。 --------------------------------------------------------------------------------part 4 0x00000000004011ab <+183>: mov 0x20(%rsp),%rbx #rbx = M[rsp + 0x20] = 指向第一个node的指针 0x00000000004011b0 <+188>: lea 0x28(%rsp),%rax #rax = R[rsp + 0x28] 0x00000000004011b5 <+193>: lea 0x50(%rsp),%rsi #rsi = R[rsp + 0x50] 0x00000000004011ba <+198>: mov %rbx,%rcx #rcx = rbx 0x00000000004011bd <+201>: mov (%rax),%rdx #rdx = M[rax] 0x00000000004011c0 <+204>: mov %rdx,0x8(%rcx) 0x00000000004011c4 <+208>: add $0x8,%rax 0x00000000004011c8 <+212>: cmp %rsi,%rax 0x00000000004011cb <+215>: je 0x4011d2 <phase_6+222> 0x00000000004011cd <+217>: mov %rdx,%rcx 0x00000000004011d0 <+220>: jmp 0x4011bd <phase_6+201> ------------------------------------------------------------------------------------ 此段在调的位置实际是0x6032d0处链表的内容,我们可以简单推断得出应该是在根据part3得到的顺序给链表重新排序, 把断点打在后面,显示一下链表值。 0x6032d0 <node1>: 0x0000014c 0x00000001 0x006032e0 0x00000000 0x6032e0 <node2>: 0x000000a8 0x00000002 0x00000000 0x00000000 0x6032f0 <node3>: 0x0000039c 0x00000003 0x00603300 0x00000000 0x603300 <node4>: 0x000002b3 0x00000004 0x00603310 0x00000000 0x603310 <node5>: 0x000001dd 0x00000005 0x00603320 0x00000000 0x603320 <node6>: 0x000001bb 0x00000006 0x006032d0 0x00000000 可以发现指针的值确实被调整了。 ------------------------------------------------------------------------------------part 5 0x00000000004011d2 <+222>: movq $0x0,0x8(%rdx) 0x00000000004011da <+230>: mov $0x5,%ebp 0x00000000004011df <+235>: mov 0x8(%rbx),%rax 0x00000000004011e3 <+239>: mov (%rax),%eax 0x00000000004011e5 <+241>: cmp %eax,(%rbx) 0x00000000004011e7 <+243>: jge 0x4011ee <phase_6+250> 0x00000000004011e9 <+245>: callq 0x40143a <explode_bomb> 0x00000000004011ee <+250>: mov 0x8(%rbx),%rbx 0x00000000004011f2 <+254>: sub $0x1,%ebp 0x00000000004011f5 <+257>: jne 0x4011df <phase_6+235> ------------------------------------------------------------------------------------ 转换成c代码 while (q -> next) { node *p = q -> next; if (p -> val > q -> val) bomb(); q = q -> next; } 遍历链表是否为单调递减 根据之前得到得结点值332,168,924,691,477,443 1, 2, 3, 4, 5, 6 我们可以得出正确的顺序应为3,4,5,6,1,2 那么我们的输入应该为4,3,2,1,6,5 结束! ------------------------------------------------------------------------------------ 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
|