琳妈 發表於 2019-10-20 00:28:00

哈密顿回路汇编语言实现(有小bug)

<div class="cnblogs_code">
<pre><span style="font-size: 15px">忠告:本代码是有bug的,有一些平行边,单点之类的情况好像没有考虑到,C++代码以及汇编代码只是给大家一个对于递归汇编程序直观的印象,并不是std,且本文的汇编实现<br>十分不好,是笔者年轻时写的一坨东西。关于更成熟的汇编语言实现递归,请参考笔者P2的那篇文章中的全排列以及汉诺塔部分。</span><br>C++实现<br>#include &lt;iostream&gt;<span style="color: rgba(0, 0, 0, 1)">
#include </span>&lt;cstdio&gt;<span style="color: rgba(0, 0, 0, 1)">
#include </span>&lt;bits/stdc++.h&gt;
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">邻接矩阵存储图,从起点开始,直接深搜,打标记,一直搜到不可以再搜,看看是不是走了n步,并且头尾相连</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> graph[<span style="color: rgba(128, 0, 128, 1)">30</span>][<span style="color: rgba(128, 0, 128, 1)">30</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">int</span> sign[<span style="color: rgba(128, 0, 128, 1)">30</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">int</span> n,m,ans=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">void</span> DFS(<span style="color: rgba(0, 0, 255, 1)">int</span> now,<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> step);
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> main() {
    </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> u,v;
    scanf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%d %d</span><span style="color: rgba(128, 0, 0, 1)">"</span>,&amp;n,&amp;m); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不妨图的顶点序号从1开始 </span>
    <span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> i=<span style="color: rgba(128, 0, 128, 1)">0</span>;i&lt;m;i++<span style="color: rgba(0, 0, 0, 1)">){
      scanf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%d %d</span><span style="color: rgba(128, 0, 0, 1)">"</span>,&amp;u,&amp;<span style="color: rgba(0, 0, 0, 1)">v);
      graph</span>=graph=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    sign[</span><span style="color: rgba(128, 0, 128, 1)">1</span>]=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
    DFS(</span><span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
    printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%d\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,ans);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">void</span> DFS(<span style="color: rgba(0, 0, 255, 1)">int</span> now,<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> step){
    </span><span style="color: rgba(0, 0, 255, 1)">if</span>(step==<span style="color: rgba(0, 0, 0, 1)">n){
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(graph[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">]){
            ans</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;   
      }
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> i=<span style="color: rgba(128, 0, 128, 1)">1</span>;i&lt;=n;i++<span style="color: rgba(0, 0, 0, 1)">){
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(!sign &amp;&amp; i!=now &amp;&amp;<span style="color: rgba(0, 0, 0, 1)"> graph){
            sign</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
            DFS    (i,step</span>+<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
            sign</span>=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
      }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">汇编实现:(有小bug,似乎会被卡单点或者两点,但特判之后反而错得更多了)<br>代码已做特殊处理<br>.macro    done
    li    $v0,</span><span style="color: rgba(128, 0, 128, 1)">10</span>
    <span style="color: rgba(0, 0, 255, 1)">syscall</span><span style="color: rgba(0, 0, 0, 1)">
.end_macro
#############################################################
.macro   initial
    li    $t0,</span><span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">for_1:</span><span style="color: rgba(0, 0, 0, 1)">
    beq    $t0,$s0,for_1_end
    sll    $t1,$t0,</span><span style="color: rgba(128, 0, 128, 1)">2</span>    #t1=t0*<span style="color: rgba(128, 0, 128, 1)">4</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> is <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)"> byte)
    </span><span style="color: rgba(0, 0, 255, 1)">add</span><span style="color: rgba(0, 0, 0, 1)">    $t1,$t1,$s3
    sw    $</span><span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>($t1)    #sign=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
    addi    $t0,$t0,</span><span style="color: rgba(128, 0, 128, 1)">1</span>    #t0=t0+<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
    j    for_1
</span><span style="color: rgba(0, 128, 128, 1)">for_1_end:</span><span style="color: rgba(0, 0, 0, 1)">
.end_macro
#############################################################
.macro    getindex(%ans,%i,%j)
    mult    %i,$t6    #i*</span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
    mflo    $t4    #t4=i*</span><span style="color: rgba(128, 0, 128, 1)">10</span>
    <span style="color: rgba(0, 0, 255, 1)">add</span>    %ans,$t4,%j    #t4=i*<span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">+j
    sll    %ans,%ans,</span><span style="color: rgba(128, 0, 128, 1)">2</span>    #ans=ans*<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
.end_macro
#############################################################
.data
</span><span style="color: rgba(0, 128, 128, 1)">matrix:</span>      .space <span style="color: rgba(128, 0, 128, 1)">400</span>
<span style="color: rgba(0, 128, 128, 1)">sign:</span>      .space <span style="color: rgba(128, 0, 128, 1)">40</span><span style="color: rgba(0, 0, 0, 1)">

#########################################################
.text
</span><span style="color: rgba(0, 128, 128, 1)">main:</span><span style="color: rgba(0, 0, 0, 1)">
    la    $s2,matrix
    la    $s3,sign
    li    $t6,</span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">      #tmp
    li    $t7,</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">      #tmp
    li    $s7,</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">      #s7 is answer
    li    $v0,</span><span style="color: rgba(128, 0, 128, 1)">5</span>
    <span style="color: rgba(0, 0, 255, 1)">syscall</span><span style="color: rgba(0, 0, 0, 1)">
    move    $s0,$v0      #s0 is n
    li    $v0,</span><span style="color: rgba(128, 0, 128, 1)">5</span>
    <span style="color: rgba(0, 0, 255, 1)">syscall</span><span style="color: rgba(0, 0, 0, 1)">
    move    $s1,$v0      #s1 is m
    initial
    li    $t0,</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">      #t0 is i
</span><span style="color: rgba(0, 128, 128, 1)">for_create:</span><span style="color: rgba(0, 0, 0, 1)">
    beq    $t0,$s1,for_create_end    #if i==m,stop </span><span style="color: rgba(0, 0, 255, 1)">add</span><span style="color: rgba(0, 0, 0, 1)"> edge
    li    $v0,</span><span style="color: rgba(128, 0, 128, 1)">5</span>
    <span style="color: rgba(0, 0, 255, 1)">syscall</span><span style="color: rgba(0, 0, 0, 1)">
    move    $t1,$v0      #t1 is u
    li    $v0,</span><span style="color: rgba(128, 0, 128, 1)">5</span>
    <span style="color: rgba(0, 0, 255, 1)">syscall</span><span style="color: rgba(0, 0, 0, 1)">
    move    $t2,$v0      #t2 is v
    getindex($t3,$t1,$t2)    #get the address </span><span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> matrix
    </span><span style="color: rgba(0, 0, 255, 1)">add</span>    $t3,$t3,$s2    #get address <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> matrix,t3 is address
    sw    $t7,</span><span style="color: rgba(128, 0, 128, 1)">0</span>($t3)    #<span style="color: rgba(0, 0, 255, 1)">add</span><span style="color: rgba(0, 0, 0, 1)"> edge (u,v)
    getindex($t3,$t2,$t1)
    </span><span style="color: rgba(0, 0, 255, 1)">add</span><span style="color: rgba(0, 0, 0, 1)">    $t3,$t3,$s2   
    sw    $t7,</span><span style="color: rgba(128, 0, 128, 1)">0</span>($t3)    #<span style="color: rgba(0, 0, 255, 1)">add</span><span style="color: rgba(0, 0, 0, 1)"> edge (v,u)
    addi    $t0,$t0,</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">    #i++
    j    for_create
</span><span style="color: rgba(0, 128, 128, 1)">for_create_end:</span><span style="color: rgba(0, 0, 0, 1)">
    sw    $t7,</span><span style="color: rgba(128, 0, 128, 1)">4</span>($s3)    #sign[<span style="color: rgba(128, 0, 128, 1)">1</span>]=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
    li    $a0,</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">      #a0 is now position
    li    $a1,</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">      #a1 is step
    jal    dfs      #the return address is </span><span style="color: rgba(0, 0, 255, 1)">in</span> $<span style="color: rgba(128, 0, 128, 1)">31</span><span style="color: rgba(0, 0, 0, 1)">
    li    $v0,</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
    li    $a0,</span><span style="color: rgba(128, 0, 128, 1)">0</span>
    <span style="color: rgba(0, 0, 255, 1)">syscall</span><span style="color: rgba(0, 0, 0, 1)">
    done
   
</span><span style="color: rgba(0, 128, 128, 1)">dfs:</span><span style="color: rgba(0, 0, 0, 1)">   
    sw    $</span><span style="color: rgba(128, 0, 128, 1)">31</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">($sp)
    addi    $sp,$sp,-</span><span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
    blt      $a1,$s0,dfs_else
    getindex($t3,$t7,$a0)
    </span><span style="color: rgba(0, 0, 255, 1)">add</span>    $t3,$t3,$s2    #t3 is address <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> matrix
    lw    $t4,</span><span style="color: rgba(128, 0, 128, 1)">0</span>($t3)    #t4=graph[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">]
    beq    $t4,</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">,arrive_ans
    addi    $sp,$sp,</span><span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
    lw    $</span><span style="color: rgba(128, 0, 128, 1)">31</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">($sp)
    jr    $</span><span style="color: rgba(128, 0, 128, 1)">31</span>      #if we don<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">t find the ans,return
    #omit something…………
dfs_else:
    jal    dfs_work
    addi    $sp,$sp,4
    lw    $31,0($sp)
    jr    $31
then:
    jr    $31      #you have jumped to main succesfully
   
arrive_ans:
    li    $s7,1
    li    $a0,1
    li    $v0,1      #print answer
    syscall
    done
    j    then      
dfs_work:
#then ,we should do something
    li    $t0,1      #t0 is i
    sw    $31,0($sp)    #save return address
    addi    $sp,$sp,-4
for_dfs1:
    bgt   $t0,$s0,for_dfs1_end
    bge    $a1,$s0,for_dfs1_end
    sw    $a0,0($sp)    #save now
    addi    $sp,$sp,-4
    sw    $a1,0($sp)    #save step
    addi    $sp,$sp,-4    #all the info was saved sucessfully
    sll    $t1,$t0,2    #t1=t0*4
    add    $t1,$t1,$s3    #t1 is the address in array_sign
    lw    $t2,0($t1)    #t2 is sign
    getindex($t3,$a0,$t0)    #t3 is
    lw    $t3,0($t3)    #t3 is graph
    beq    $t2,1,else    #if sign==1,return
    beq    $t0,$a0,else    #if i==now,return
    beq    $t3,0,else    #if graph==0,return
    sw    $t7,0($t1)    #sign=1;
    sw    $t0,0($sp)    #save tmpi in stack
    addi    $sp,$sp,-4
    sw    $t1,0($sp)    #save the address in array_sign
    addi    $sp,$sp,-4
    move    $a0,$t0      #now=i
    addi    $a1,$a1,1    #step++
    jal    dfs      #next recursion
   
    addi    $sp,$sp,4
    lw    $t1,0($sp)    #fetch the address in array_sign
    addi    $sp,$sp,4
    lw    $t0,0($sp)    #fetch i
    sw    $t7,0($t1)    #sign=0
    addi    $sp,$sp,4
    lw    $a1,0($sp)
    addi    $sp,$sp,4
    lw    $a0,0($sp)    #fetch all the things
    addi    $t0,$t0,1    #i++
    j    for_dfs1

for_dfs1_end:
    addi    $sp,$sp,4
    lw    $31,0($sp)    #fetch the leeway
    jr    $31


else:
    addi    $t0,$t0,1
    addi    $sp,$sp,4
    lw    $a1,0($sp)
    addi    $sp,$sp,4
    lw    $a0,0($sp)    #fetch all the things
    j    for_dfs1</span></pre>
</div>
<p>&nbsp;</p>
<p>用汇编语言写递归程序的经验教训:</p>
<p>1.值的进栈与出栈:这个一定要注意,每次调用其他过程的时候,都要想想是不是要把退路保存下来,把原来的变量保存下来,有些甚至不止保存一次,有些甚至会因为分支而要在各个分支中进栈出栈。递归的还得多练,这次居然写了六个小时还被卡了一个点,由此可见我P2大概率会被干掉。</p>
<p>2.判断条件的书写:很多时候<strong>用相等判断beq并不够</strong>(因为自己写的程序太混乱,值会超过预期),我们需要能判断大于等于,小于等于,严格小,严格大的指令,至于到底使用哪种,一定要在写代码的时候想好。循环退出的条件一般写在循环的最前面。最好每个条件判断后面都写上清晰的注释。</p>
<p>3.别怕。汇编程序看着长,实际上重复的部分有很多是进栈出栈,以后写的时候不能再抓狂到砸东西了!</p><br><br>
来源:https://www.cnblogs.com/BUAA-Wander/p/11706452.html
頁: [1]
查看完整版本: 哈密顿回路汇编语言实现(有小bug)