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
| Dump of assembler code for function phase_6: 0x00401500 <+0>: addiu sp,sp,-96 0x00401504 <+4>: sw ra,92(sp) 0x00401508 <+8>: sw s8,88(sp) 0x0040150c <+12>: move s8,sp 0x00401510 <+16>: lui gp,0x42 0x00401514 <+20>: addiu gp,gp,-20080 0x00401518 <+24>: sw gp,16(sp) 0x0040151c <+28>: sw a0,96(s8) 0x00401520 <+32>: lui v0,0x41 0x00401524 <+36>: addiu v0,v0,12592 0x00401528 <+40>: sw v0,32(s8) 0x0040152c <+44>: addiu v0,s8,36 0x00401530 <+48>: lw a0,96(s8) 0x00401534 <+52>: move a1,v0 0x00401538 <+56>: jal 0x401ba8 <read_six_numbers> 0x0040153c <+60>: nop 0x00401540 <+64>: lw gp,16(s8) 0x00401544 <+68>: sw zero,28(s8) # 令28(s8) = 0,猜测是循环计次变量 0x00401548 <+72>: b 0x40163c <phase_6+316> # 到+316行 0x0040154c <+76>: nop 0x00401550 <+80>: lw v0,28(s8) # v0 = i 0x00401554 <+84>: nop 0x00401558 <+88>: sll v0,v0,0x2 # v0 *= 4 0x0040155c <+92>: addiu v1,s8,24 # v1 = s8+24 地址 0x00401560 <+96>: addu v0,v1,v0 0x00401564 <+100>: lw v0,12(v0) # 再算上这个12,本质从36开始取,取num[i]到v0 0x00401568 <+104>: nop 0x0040156c <+108>: slti v0,v0,7 # v0=(num[i]<7) 0x00401570 <+112>: beqz v0,0x40159c <phase_6+156> # 当num[i]>=7就跳+156行爆炸,所以六个数都要小于7 0x00401574 <+116>: nop 0x00401578 <+120>: lw v0,28(s8) # v0 = 循环计次量i 0x0040157c <+124>: nop 0x00401580 <+128>: sll v0,v0,0x2 # v0 *= 4 0x00401584 <+132>: addiu v1,s8,24 0x00401588 <+136>: addu v0,v1,v0 0x0040158c <+140>: lw v0,12(v0) # 再算上这个12,本质从36开始取,取num[i]到v0 0x00401590 <+144>: nop 0x00401594 <+148>: bgtz v0,0x4015a8 <phase_6+168> # 判断是否大于0,大于就跳+168或者就下一行爆炸,到这里得到了六个数都是[1,6]间的数 0x00401598 <+152>: nop 0x0040159c <+156>: jal 0x4021f0 <explode_bomb> 0x004015a0 <+160>: nop 0x004015a4 <+164>: lw gp,16(s8) 0x004015a8 <+168>: lw v0,28(s8) # v0 = 循环计次量i 0x004015ac <+172>: nop 0x004015b0 <+176>: addiu v0,v0,1 # v0++ 0x004015b4 <+180>: sw v0,24(s8) # 令24(s8) = v0,好像也是计次变量,但从1开始 0x004015b8 <+184>: b 0x401618 <phase_6+280> # 跳 0x004015bc <+188>: nop 0x004015c0 <+192>: lw v0,28(s8) # v0 = 循环计次量i 0x004015c4 <+196>: nop 0x004015c8 <+200>: sll v0,v0,0x2 # v0 *= 2 0x004015cc <+204>: addiu v1,s8,24 0x004015d0 <+208>: addu v0,v1,v0 0x004015d4 <+212>: lw v1,12(v0) # 上面几条就是取v1 = num[i] 0x004015d8 <+216>: lw v0,24(s8) # v0 = 24(s8) 这是啥,上次的i,也就是i-1 0x004015dc <+220>: nop 0x004015e0 <+224>: sll v0,v0,0x2 0x004015e4 <+228>: addiu a0,s8,24 0x004015e8 <+232>: addu v0,a0,v0 0x004015ec <+236>: lw v0,12(v0) # 取v0 = num[24(s8)] 0x004015f0 <+240>: nop 0x004015f4 <+244>: bne v1,v0,0x401608 <phase_6+264> # 两个不相等的时候跳过炸弹,现在的意思是相邻两个不相等蛤? 0x004015f8 <+248>: nop 0x004015fc <+252>: jal 0x4021f0 <explode_bomb> 0x00401600 <+256>: nop 0x00401604 <+260>: lw gp,16(s8) 0x00401608 <+264>: lw v0,24(s8) # v0 = 24(s8) 0x0040160c <+268>: nop 0x00401610 <+272>: addiu v0,v0,1 # v0++ 0x00401614 <+276>: sw v0,24(s8) # 24(s8) = v0 0x00401618 <+280>: lw v0,24(s8) # 蛤?好像是双循环,i=0->5,j=i+1->5,使得六个数互不相等 0x0040161c <+284>: nop 0x00401620 <+288>: slti v0,v0,6 # v0 = (循环计次量i<6) 0x00401624 <+292>: bnez v0,0x4015c0 <phase_6+192> # 若v0!=0就到+192行 0x00401628 <+296>: nop 0x0040162c <+300>: lw v0,28(s8) 0x00401630 <+304>: nop 0x00401634 <+308>: addiu v0,v0,1 0x00401638 <+312>: sw v0,28(s8) 0x0040163c <+316>: lw v0,28(s8) # v0 = 28(s8) = 循环计次变量 0x00401640 <+320>: nop 0x00401644 <+324>: slti v0,v0,6 # 从0~5,共6次 0x00401648 <+328>: bnez v0,0x401550 <phase_6+80> # 进入循环体 0x0040164c <+332>: nop 0x00401650 <+336>: sw zero,28(s8) # 从上一个双重循环出来,28(s8)=0 0x00401654 <+340>: b 0x4016f8 <phase_6+504> # 跳到+504 0x00401658 <+344>: nop 0x0040165c <+348>: lui v0,0x41 # v0 = 0x41 0x00401660 <+352>: addiu v0,v0,12592 # v0 += 12592 0x00401664 <+356>: sw v0,32(s8) # 32(s8) = v0 此时发现32(s8)是node1的指针 0x00401668 <+360>: li v0,1 # v0 = 1 0x0040166c <+364>: sw v0,24(s8) # 24(s8) = v0 0x00401670 <+368>: b 0x40169c <phase_6+412> # 进入,应该是第二重循环了 0x00401674 <+372>: nop # ------------------------------这一部分是链表指针后移, 32(s8)是current指针 0x00401678 <+376>: lw v0,32(s8) # v0=32(s8) node1的地址(x *(*($s8+32))) 0x0040167c <+380>: nop 0x00401680 <+384>: lw v0,8(v0) # v0=8(v0) node2的地址 0x00401684 <+388>: nop 0x00401688 <+392>: sw v0,32(s8) # node1的地址指向node2 # ------------------------------这一部分是链表指针后移, 32(s8)是current指针 0x0040168c <+396>: lw v0,24(s8) # v0 = 24(s8) 0x00401690 <+400>: nop 0x00401694 <+404>: addiu v0,v0,1 # v0++了 0x00401698 <+408>: sw v0,24(s8) # 24(s8) = v0 0x0040169c <+412>: lw v0,28(s8) # v0 = 28(s8) 外层循环变量 0x004016a0 <+416>: nop 0x004016a4 <+420>: sll v0,v0,0x2 # v0 *= 4 0x004016a8 <+424>: addiu v1,s8,24 0x004016ac <+428>: addu v0,v1,v0 0x004016b0 <+432>: lw v1,12(v0) # 意思是取36(s8)开始的即输入的第24(s8)个参数到v1 0x004016b4 <+436>: lw v0,24(s8) # 取v0 = 24(s8) 0x004016b8 <+440>: nop 0x004016bc <+444>: slt v0,v0,v1 # v0 = (num[j] < num[i]) 0x004016c0 <+448>: bnez v0,0x401678 <phase_6+376> # 上式满足的话进入+376行 0x004016c4 <+452>: nop 0x004016c8 <+456>: lw v0,28(s8) # v0 = 28(s8) , 外层循环 0x004016cc <+460>: nop 0x004016d0 <+464>: sll v0,v0,0x2 # v0 *= 2 0x004016d4 <+468>: addiu v1,s8,24 0x004016d8 <+472>: addu v0,v1,v0 0x004016dc <+476>: lw v1,32(s8) # 取v1 = node的地址 0x004016e0 <+480>: nop 0x004016e4 <+484>: sw v1,36(v0) # 60之后(s8) = node的地址 0x004016e8 <+488>: lw v0,28(s8) # v0 = 28(s8) = i 0x004016ec <+492>: nop 0x004016f0 <+496>: addiu v0,v0,1 # v0++ 0x004016f4 <+500>: sw v0,28(s8) # 保存 0x004016f8 <+504>: lw v0,28(s8) # v0 = 28(s8) 0x004016fc <+508>: nop 0x00401700 <+512>: slti v0,v0,6 # 也是循环6次 0x00401704 <+516>: bnez v0,0x40165c <phase_6+348> # 进入循环体 0x00401708 <+520>: nop 0x0040170c <+524>: lw v0,60(s8) # 拿链表指针数组[0]到v0 0x00401710 <+528>: nop 0x00401714 <+532>: sw v0,32(s8) # 存到32(s8) 0x00401718 <+536>: li v0,1 # v0=1 0x0040171c <+540>: sw v0,28(s8) # 28(s8) = v0 = 1 0x00401720 <+544>: b 0x40177c <phase_6+636> # 又要进循环了 0x00401724 <+548>: nop 0x00401728 <+552>: lw v0,28(s8) # v0=i 0x0040172c <+556>: nop 0x00401730 <+560>: sll v0,v0,0x2 # v0 *= 4 0x00401734 <+564>: addiu v1,s8,24 0x00401738 <+568>: addu v0,v1,v0 0x0040173c <+572>: lw v1,36(v0) # v1 = 链表指针数组[i] 0x00401740 <+576>: lw v0,32(s8) # v0 = current 0x00401744 <+580>: nop 0x00401748 <+584>: sw v1,8(v0) # v0.next = v1 ------重点 0x0040174c <+588>: lw v0,28(s8) # v0 = i 0x00401750 <+592>: nop 0x00401754 <+596>: sll v0,v0,0x2 0x00401758 <+600>: addiu v1,s8,24 0x0040175c <+604>: addu v0,v1,v0 0x00401760 <+608>: lw v0,36(v0) # v0 = 链表指针数组[i] 0x00401764 <+612>: nop 0x00401768 <+616>: sw v0,32(s8) # 32(s8) = 链表指针数组[i] 0x0040176c <+620>: lw v0,28(s8) # v0 = i 0x00401770 <+624>: nop 0x00401774 <+628>: addiu v0,v0,1 0x00401778 <+632>: sw v0,28(s8) # v0++存入 0x0040177c <+636>: lw v0,28(s8) 0x00401780 <+640>: nop 0x00401784 <+644>: slti v0,v0,6 0x00401788 <+648>: bnez v0,0x401728 <phase_6+552> # 正式进循环 # 所以上循环作用就是,链表重排 0x0040178c <+652>: nop 0x00401790 <+656>: lw v0,32(s8) # v0 = 32(s8) = 尾节点(最后留的指针) 0x00401794 <+660>: nop 0x00401798 <+664>: sw zero,8(v0) # 尾节点.next = 0 0x0040179c <+668>: lw v0,60(s8) # v0 = 头节点 0x004017a0 <+672>: nop 0x004017a4 <+676>: sw v0,32(s8) # 32(s8) = 头节点指针 0x004017a8 <+680>: sw zero,28(s8) # i = 0 0x004017ac <+684>: b 0x401878 <phase_6+888> # 进+888行 0x004017b0 <+688>: nop 0x004017b4 <+692>: lw v0,-32660(gp) # v0为学号第一位 0x004017b8 <+696>: nop 0x004017bc <+700>: lw v0,44(v0) # v0=学号第12位 0x004017c0 <+704>: nop 0x004017c4 <+708>: andi v0,v0,0x1 # 学号第十二位&=1 0x004017c8 <+712>: andi v0,v0,0xff # 学号第十二位&=255 0x004017cc <+716>: beqz v0,0x401818 <phase_6+792> # 我学号最后一位为0,然后进去了,应该是分支,不同分支不同要求 0x004017d0 <+720>: nop 0x004017d4 <+724>: lw v0,32(s8) 0x004017d8 <+728>: nop 0x004017dc <+732>: lw v1,0(v0) 0x004017e0 <+736>: lw v0,32(s8) 0x004017e4 <+740>: nop 0x004017e8 <+744>: lw v0,8(v0) 0x004017ec <+748>: nop 0x004017f0 <+752>: lw v0,0(v0) 0x004017f4 <+756>: nop 0x004017f8 <+760>: slt v0,v1,v0 0x004017fc <+764>: beqz v0,0x401854 <phase_6+852> 0x00401800 <+768>: nop 0x00401804 <+772>: jal 0x4021f0 <explode_bomb> 0x00401808 <+776>: nop 0x0040180c <+780>: lw gp,16(s8) 0x00401810 <+784>: b 0x401854 <phase_6+852> 0x00401814 <+788>: nop 0x00401818 <+792>: lw v0,32(s8) # 取链表指针数组头 0x0040181c <+796>: nop 0x00401820 <+800>: lw v1,0(v0) # v1 = 当前节点内容 0x00401824 <+804>: lw v0,32(s8) 0x00401828 <+808>: nop 0x0040182c <+812>: lw v0,8(v0) # v0 = 链表指针数组头.next的地址 0x00401830 <+816>: nop 0x00401834 <+820>: lw v0,0(v0) # v0 = 链表指针数组头.next的内容了 0x00401838 <+824>: nop 0x0040183c <+828>: slt v0,v0,v1 # 要求 v0 >= v1, 肉眼看感觉很费脑筋啊,display *(*($s8+32)) 和 display *(*( (*($s8+32))+8 ))一下,第二个变量一直是725应该我的分支要求,现在就是看第一个怎么得来的 0x00401840 <+832>: beqz v0,0x401854 <phase_6+852> # 这里爆炸 0x00401844 <+836>: nop 0x00401848 <+840>: jal 0x4021f0 <explode_bomb> 0x0040184c <+844>: nop 0x00401850 <+848>: lw gp,16(s8) 0x00401854 <+852>: lw v0,32(s8) # v0 = 取链表指针数组头的地址 0x00401858 <+856>: nop 0x0040185c <+860>: lw v0,8(v0) # v0 = 取链表指针数组头.next的地址 0x00401860 <+864>: nop 0x00401864 <+868>: sw v0,32(s8) # 存到32(s8) 0x00401868 <+872>: lw v0,28(s8) 0x0040186c <+876>: nop 0x00401870 <+880>: addiu v0,v0,1 0x00401874 <+884>: sw v0,28(s8) 0x00401878 <+888>: lw v0,28(s8) # 又一个循环 0x0040187c <+892>: nop 0x00401880 <+896>: slti v0,v0,5 # 这一次是从[0~5),4次 0x00401884 <+900>: bnez v0,0x4017b4 <phase_6+692> # 这一循环是判重排链表非递减序 0x00401888 <+904>: nop 0x0040188c <+908>: move sp,s8 0x00401890 <+912>: lw ra,92(sp) 0x00401894 <+916>: lw s8,88(sp) 0x00401898 <+920>: addiu sp,sp,96 0x0040189c <+924>: jr ra 0x004018a0 <+928>: nop End of assembler dump.
读入:%d %d %d %d %d %d 要求链表重排 链表节点node1~6 大小分别是 253,725,301,997,212,432 最后的顺序是node5_node1_node3_node6_node2_node4 要求重排成这个样子 重排程序中,对于第i个数,1~6个数中有多少个小于num[i],就取node几+1(因为执行了那么多次next()) 那么第一个数应取node5,即执行4次next(),为5的时候有4个数小于5,第一个数取5 剩下同理 第六关答案为 5 1 3 6 2 4
|