MARS MIPS汉诺塔实现中输出步骤编号缺失问题求助
MIPS汉诺塔实现:修复步骤编号缺失问题
需求与问题
用MARS 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
尝试过的无效方案
- 模拟C/C++引用传参实现,未生效;
- 使用全局变量/
$gp寄存器存储计数器,但未处理整数转ASCII的关键步骤,调试无果。
修复方案
核心问题是缺少全局步骤计数器和整数转ASCII写入文件的逻辑,修复后的完整代码如下:
# Towers of Hanoi # MIPS assembly implementation (tested with MARS) .data prompt: .asciiz "Enter a number: " part1: .asciiz "\nStep " # 修正为需求的Step字符串 part2: .asciiz ": " part3: .asciiz "=>" # 修正为需求的=>格式 fout: .asciiz "TOWER_OF_HANOI.txt" # filename for output temp: .byte # store the character A, B, C in the file step_counter: .word 0 # 全局步骤计数器 temp_str: .space 2 # 临时存储步骤编号的ASCII字符串 .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 # 初始化步骤计数器为0 la $t0, step_counter sw $zero, 0($t0) # 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 ########################################################### # Close 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 ################################################################################## output: # 递增步骤计数器 la $t0, step_counter lw $t2, 0($t0) addi $t2, $t2, 1 sw $t2, 0($t0) # 打印Step到控制台 li $v0, 4 la $a0, part1 syscall # 写入Step到文件 li $v0, 15 move $a0, $s6 la $a1, part1 li $a2, 6 # "\nStep "的字节长度 syscall # 打印步骤编号到控制台 li $v0, 1 move $a0, $t2 syscall # 将步骤编号转为ASCII并写入文件 la $t3, temp_str li $t4, 10 div $t2, $t4 mfhi $t5 # 个位 mflo $t6 # 十位 beq $t6, $zero, single_digit # 两位数处理 addi $t6, $t6, 48 sb $t6, 0($t3) addi $t5, $t5, 48 sb $t5, 1($t3) li $a2, 2 j write_num single_digit: # 一位数处理 addi $t5, $t5, 48 sb $t5, 0($t3) li $a2, 1 write_num: li $v0, 15 move $a0, $s6 move $a1, $t3 syscall # 打印: 到控制台 li $v0, 4 la $a0, part2 syscall # 写入: 到文件 li $v0, 15 move $a0, $s6 la $a1, part2 li $a2, 2 syscall # 打印起始塔到控制台 li $v0, 11 add $a0, $s1, $zero sb $a0, temp syscall # 写入起始塔到文件 li $v0, 15 move $a0, $s6 la $a1, temp li $a2, 1 syscall # 打印=>到控制台 li $v0, 4 la $a0, part3 syscall # 写入=>到文件 li $v0, 15 move $a0, $s6 la $a1, part3 li $a2, 2 syscall # 打印目标塔到控制台 li $v0, 11 add $a0, $s2, $zero sb $a0, temp syscall # 写入目标塔到文件 li $v0, 15 move $a0, $s6 la $a1, temp li $a2, 1 syscall beq $s0, $t1, exithanoi j recur2
修复要点
- 新增全局计数器:在
.data段添加step_counter,main中初始化为0,每次进入output时递增; - 整数转ASCII:MARS的文件写入只能处理字节/字符串,因此需要将整数编号转为对应的ASCII字符(数字+48得到ASCII值),支持一位和两位数;
- 修正字符串常量:把
part1改为"\nStep ",part3改为"=>",匹配需求格式; - 调整写入长度:根据实际字符串长度修改
syscall 15的$a2参数,避免写入多余或缺失字节。
内容的提问来源于stack exchange,提问作者Lucifer
相关产品推荐
相关产品推荐

