Assembly MIPS组装中的河内塔

Assembly MIPS组装中的河内塔,assembly,mips,towers-of-hanoi,Assembly,Mips,Towers Of Hanoi,我想在MIPS汇编中实现Hanoi Towers算法 杆由A、B和C表示 输入是磁盘的数量,输出是解决问题所需的移动顺序 例如: 如果输入为3,则输出应为: A>C A>B C>B A>C B>A B>C A>C 我已经设法用棒的编号得到结果,即1>3,而不是A>C,代码如下: .data NewLine: .asciiz "\n" To: .asciiz ">" .globl main .text main:

我想在MIPS汇编中实现Hanoi Towers算法

杆由
A
B
C
表示

输入是磁盘的数量,输出是解决问题所需的移动顺序

例如: 如果输入为
3
,则输出应为:

A>C
A>B
C>B
A>C
B>A
B>C
A>C
我已经设法用棒的编号得到结果,即
1>3
,而不是
A>C
,代码如下:

.data

NewLine: .asciiz      "\n"
To: .asciiz      ">"

.globl main
.text  

main:

  li $v0, 5
  syscall
  add $a0, $v0, $zero 

  addi $a1, $zero, 1        
  addi $a2, $zero, 3        
  addi $a3, $zero, 2        
  jal hanoi1

  li $v0, 10            
  syscall

hanoi1:        

  addi $t0, $a0, 0  
  addi $t1, $zero, 1
  bne $a0, $t1, hanoi2
  li $v0, 1             
  move $a0, $a1
  syscall
  li $v0, 4         
  la $a0, To
  syscall
  li $v0, 1             
  move $a0, $a2
  syscall
  li $v0, 4         
  la $a0, NewLine
  syscall
  addi $a0, $t0, 0      
  jr $ra

hanoi2:

  addi $sp, $sp, -20

  sw $ra, 16($sp)
  sw $a3, 12($sp)       
  sw $a2, 8($sp)    
  sw $a1, 4($sp)    
  sw $a0, 0($sp)        

  addi $t3, $a3, 0      
  addi $a3, $a2, 0      
  addi $a2, $t3, 0      
  addi $a0, $a0, -1             
  jal hanoi1   

  lw $ra, 16($sp)
  lw $a3, 12($sp)       
  lw $a2, 8($sp)        
  lw $a1, 4($sp)        
  lw $a0, 0($sp)        

  addi $t0, $a0, 0      
  addi $t1, $zero, 1
  li $v0, 1             
  move $a0, $a1
  syscall
  li $v0, 4         
  la $a0, To
  syscall
  li $v0, 1             
  move $a0, $a2
  syscall
  li $v0, 4         
  la $a0, NewLine
  syscall
  addi $a0, $t0, 0      

  addi $t3, $a3, 0      
  addi $a3, $a1, 0      
  addi $a1, $t3, 0      
  addi $a0, $a0, -1             
  jal hanoi1 
  lw $ra, 16($sp)

  addi $sp, $sp, 20

  add $v0, $zero, $t5
  jr $ra    
我尝试添加标签,例如:

PrintA:
  li  $v0, 4 
  la  $a0, A
  syscall
  jr $ra
并将
beq
添加到右侧标签的分支:

beq $a1, $t7, PrintA # $t7=1
beq $a1, $t8, PrintB # $t8=2
beq $a1, $t9, PrintC # $t9=3
但是程序进入了无限循环,可能是因为我没有正确处理
$ra

所以我的问题是我不知道如何把棒的数字转换成字母


任何帮助都将不胜感激。

要使用
jr$ra
返回某处,您必须首先将register
$ra
设置为要返回的地址,这就是
jal
在分支之前所做的,将下一条指令的地址放入
ra

也就是说,要使用这个:

    beq $a1, $t7, PrintA # $t7=1
    beq $a1, $t8, PrintB # $t8=2
    beq $a1, $t9, PrintC # $t9=3
由于
PrintA/B/C
变量以
jr$ra
结尾,这意味着如果您不想在那里打印任何内容,那么下一条指令而不是
beq
块也将是
jr$ra
,从而结束该代码流

然后,您可以这样做:

    move $a0, <number of rod (from)>
    # make sure you have current `ra` stored in stack to not lose it
    jal  print_rod    # will set ra to address of next line
    ... continue with printing "To" string
    ... and then you can reuse the same subroutine to display second rod
    move $a0, <number of rod (to)>
    jal  print_rod    # will set ra to address of next line
    ... do remaining things (? if any), restore ra, continue
只需稍加修改:

  li     $v0, 11       # print character service
  addi   $a0, $a1, 64  # number to ASCII letter (1->A, 2->B, 3->C)
  syscall
就是这样,没有分支(分支通常比做简单的计算慢,比如
addi

您当前的源代码的不同部分与其他部分相同,您希望再次花费一些时间来尝试了解代码的哪些部分不同,并仅保留这些部分,并使用单个代码实现相同的路径,或者将相同的代码提取到子例程中(通过
jal subroutine+jr$ra
使用它),或者重新安排代码流,如下所示:

  # something to be done in every iteration
  # if (next_part_should_not_execute) branch to skip_part_2
  # part 2 of code - being run just under certain condition
skip_part_2:
  # if (next_part_should_not_execute) branch to skip_part_3
  # part 3 of code - being run just under certain other condition
skip_part_3:
  # part 4 of code, being run every iteration, unconditionally
这样,在源代码中仍然只需要“Part4”指令的一个副本,但只有在某些条件为真时,才会运行Part2和Part3

  # something to be done in every iteration
  # if (next_part_should_not_execute) branch to skip_part_2
  # part 2 of code - being run just under certain condition
skip_part_2:
  # if (next_part_should_not_execute) branch to skip_part_3
  # part 3 of code - being run just under certain other condition
skip_part_3:
  # part 4 of code, being run every iteration, unconditionally