assembly 更正“河内塔MIPS”的输出[重复]

ckx4rj1h  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(124)

此问题在此处已有答案

Saving integers as Strings in MIPS(3个答案)
26天前关闭。
我试图解决“塔的河内”问题使用火星MIPS.输出然后写在文件“TOWER_OF_HANOI.txt”与以下格式:

Step 1: A=>B
Step 2: A=>C
Step 3: B=>C
...

字符串
到目前为止,我已经实现了问题的指令部分,但仍在努力纠正我的输出。我的只是:

Step : A=>B
Step : A=>C
...


下面是我的实现:

# Towers of Hanoi
# MIPS assembly implementation (tested with MARS)

.data
prompt: .asciiz "Enter a number: "
part1: .asciiz "\nStage "
part2: .asciiz ": "
part3: .asciiz "==>"
fout:   .asciiz "TOWER_OF_HANOI.txt"      # filename for output
temp: .byte               # store the character A, B, C in the file

.text
.globl main
#########################################################################
# Open (for writing) a file that does not exist
    li   $v0, 13       # system call for open file
    la   $a0, fout     # output file name
    li   $a1, 1        # Open for writing (flags are 0: read, 1: write)
    li   $a2, 0        # mode is ignored
    syscall            # open a file (file descriptor returned in $v0)
    move $s6, $v0      # save the file descriptor 
  
#########################################################################
main:
    li $v0,  4          # print string
        la $a0,  prompt
        syscall
        li $v0,  5          # read integer
        syscall

    # parameters for the routine
        add $a0, $v0, $zero # move to $a0
        li $a1, 'A'
        li $a2, 'B'
        li $a3, 'C'

        jal hanoi           # call hanoi routine
###########################################################
# ?óng file
    li   $v0, 16       # system call for close file
    move $a0, $s6      # file descriptor to close
    syscall            # close file
    
        li $v0, 10          # exit
        syscall
###########################################################
hanoi:

    #save in stack
    addi $sp, $sp, -20 
    sw   $ra, 0($sp)
    sw   $s0, 4($sp)
    sw   $s1, 8($sp)
    sw   $s2, 12($sp)
    sw   $s3, 16($sp)

    add $s0, $a0, $zero
    add $s1, $a1, $zero
    add $s2, $a2, $zero
    add $s3, $a3, $zero

    addi $t1, $zero, 1
    beq $s0, $t1, output

    recur1:

        addi $a0, $s0, -1
        add $a1, $s1, $zero
        add $a2, $s3, $zero
        add $a3, $s2, $zero
        jal hanoi

        j output

    recur2:

        addi $a0, $s0, -1
        add $a1, $s3, $zero
        add $a2, $s2, $zero
        add $a3, $s1, $zero
        jal hanoi

    exithanoi:

        lw   $ra, 0($sp)        # restore registers from stack
        lw   $s0, 4($sp)
        lw   $s1, 8($sp)
        lw   $s2, 12($sp)
        lw   $s3, 16($sp)

        addi $sp, $sp, 20       # restore stack pointer

        jr $ra
##################################################################################3
    output:

        li $v0,  4              # print string
        la $a0,  part1
        syscall
        
          # Write to file just opened
    li   $v0, 15       # system call for write to file
    move $a0, $s6      # file descriptor 
    la   $a1, part1   # address of buffer from which to write
    li   $a2, 5       # hardcoded buffer length
    syscall            # write to file

        
        li $v0,  4              # print string
        la $a0,  part2
        syscall
        
          # Write to file just opened
    li   $v0, 15       # system call for write to file
    move $a0, $s6      # file descriptor 
    la   $a1, part2   # address of buffer from which to write
    li   $a2, 2       # hardcoded buffer length
    syscall            # write to file
        
        li $v0,  11             # print character
        add $a0, $s1, $zero
        sb $a0, temp
        syscall
        
          # Write to file just opened
    li   $v0, 15       # system call for write to file
    move $a0, $s6      # file descriptor 
    la   $a1, temp     # address of buffer from which to write
    li   $a2, 1        # hardcoded buffer length
    syscall            # write to file
       
        li $v0,  4              # print string
        la $a0,  part3
        syscall
        
          # Write to file just opened
    li   $v0, 15       # system call for write to file
    move $a0, $s6      # file descriptor 
    la   $a1, part3   # address of buffer from which to write
    li   $a2, 3       # hardcoded buffer length
    syscall            # write to file
        
        li $v0,  11             # print character
        add $a0, $s2, $zero
        sb $a0, temp
        syscall
        
          # Write to file just opened
    li   $v0, 15       # system call for write to file
    move $a0, $s6      # file descriptor 
    la   $a1, temp     # address of buffer from which to write
    li   $a2, 1       # hardcoded buffer length
    syscall            # write to file

    
    
        beq $s0, $t1, exithanoi
        j recur2


我对此有两种方法:
1.第一种方法类似于C/C++中的函数传递引用。我试过将其转换为MIPS,但不起作用
1.第二个是使用全局变量,在.text部分声明或使用寄存器$gp。我花了几个小时观察寄存器中的变化,但一无所获。

bvn4nwqk

bvn4nwqk1#

您可以使用一些备用寄存器来跟踪当前的迭代次数。

li $t7, 0  # Counter

字符串
然后在每次迭代中递增

addiu $t7, $t7, 1


保留一个缓冲区来将这个整数转换为它的字符串表示。所以在你的数据部分:

itoa: .asciiz "ITOAITOA"
itoa_end:


然后在将Stage写入输出文件后,将整数转换为字符串并将其写入文件:

# itoa
    la $a1, itoa_end
    addiu $a1, $a1, -1
    li $t6, 10
    li $a2, 0
    move $t5, $t7
itoa_loop:    
    addiu $a1, $a1, -1
    addiu $a2, $a2, 1
    divu $t5, $t6        
    mfhi $t5
    addiu $t5, $t5, '0'
    sb $t5, 0($a1)
    mflo $t5
    bnez $t5, itoa_loop

    li $v0, 15
    move $a0, $s6
    syscall

相关问题