哈密顿回路汇编语言实现(有小bug)
<div class="cnblogs_code"><pre><span style="font-size: 15px">忠告:本代码是有bug的,有一些平行边,单点之类的情况好像没有考虑到,C++代码以及汇编代码只是给大家一个对于递归汇编程序直观的印象,并不是std,且本文的汇编实现<br>十分不好,是笔者年轻时写的一坨东西。关于更成熟的汇编语言实现递归,请参考笔者P2的那篇文章中的全排列以及汉诺塔部分。</span><br>C++实现<br>#include <iostream><span style="color: rgba(0, 0, 0, 1)">
#include </span><cstdio><span style="color: rgba(0, 0, 0, 1)">
#include </span><bits/stdc++.h>
<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>,&n,&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<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>,&u,&<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<=n;i++<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!sign && i!=now &&<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> </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]