Recursion 使用堆栈的MIPS代码产生递归错误

Recursion 使用堆栈的MIPS代码产生递归错误,recursion,stack,mips,Recursion,Stack,Mips,在本作业中,我必须将任何给定的数字从基数33(1-9、A-W和A-W)转换为基数10。如果输入为空,则显示消息“input is empty”(输入为空)。如果输入不是数字或字母A-W,则输出为:“输入无效”。这个程序必须使用堆栈和递归 我写了一个没有堆栈的程序,它正在运行。我现在正试图将其转换到一个使用堆栈的程序中,但不管我输入什么,都会得到“Input is empty”的消息 这是我的MIPS代码: ############### Base 33 to Base 10 Converter

在本作业中,我必须将任何给定的数字从基数33(1-9、A-W和A-W)转换为基数10。如果输入为空,则显示消息“input is empty”(输入为空)。如果输入不是数字或字母A-W,则输出为:“输入无效”。这个程序必须使用堆栈和递归

我写了一个没有堆栈的程序,它正在运行。我现在正试图将其转换到一个使用堆栈的程序中,但不管我输入什么,都会得到“Input is empty”的消息

这是我的MIPS代码:

############### Base 33 to Base 10 Converter ###################
.data
  userInput:    .space  700
  empty:   .asciiz "Input is empty."
   long:    .asciiz "Input is too long."
  invalid: .asciiz "Invalid base-33 number."

.text
ErrorLong:
#prints message for input that is too long
  la $a0, long
  li $v0, 4
  syscall
  j end

ErrorInvalid:
#prints message for invalid input
  la $a0, invalid
  li $v0, 4
  syscall
  j end

ErrorEmpty:
#prints message for empty string
  la $a0, empty
  li $v0, 4
  syscall
  j end

.globl main
main:
addi $sp, $sp, -16
  li $v0, 8
  la $a0, userInput
  li $a1, 200
  syscall

 sw $a0, 0($sp) # put into stack the memory address where user input is 

or $a0, $0, $0
sw $ra, 12($sp)
jal Number
lw $ra, 0($sp)
#TEST FOR END
#la $a0, strEnd
ori $a0, $a0, 4
syscall
#end
jr $ra

Number:
addi $sp,$sp,-4
lb $t8, 0($sp)
###################
Rid:
#takes care of leading spaces
li $t9, 32 # space
beq $t9, $t8, Character
move $t8, $a0  ############
j length
addi $sp,$sp,4

Character:
addi $a0, $a0, 1
j Rid

#takes care of length
length:
addi $t0, $t0, 0
addi $t1, $t1, 10
add $t2, $t2, $a0

addi $sp,$sp,-4
lb $s2, 0($sp)
#itertates through the array
traverse:
beqz $s2, discovered
beq $s2, $t1, discovered
addi $a0, $a0, 1
addi $t0, $t0, 1
j traverse
addi $sp,$sp,4

#busted empty space or input that violates limit
discovered:
#if it's empty go to case for empty which outputs 
beqz $t0, ErrorEmpty
slti $t4, $t0, 5
#if it's too long, go to case for too long and print 
beqz $t4, ErrorLong
move $sp, $t2
#go to next verification process
j verify

addi $sp,$sp,-4
lb $s3, 0($sp)  #loads address here
#checks inputs
verify:
beqz $s3, initial
beq $s3, $t1, initial
slti $t3, $s3, 48                 #invalid for anything below 0
bne $t3, $zero, ErrorInvalid
slti $t3, $s3, 58                 #legal input for everything less than or equal to 9
bne $t3, $zero, Move
slti $t3, $s3, 65                 #legal input for everything less than or equal to 65,  'a'
bne $t3, $zero, Move
slti $t3, $s3, 88                 #legal input for anything less than or equal to 88
bne $t3, $zero, Move
slti $t3, $s3, 97                 # invalid input, not numerical nor alphabetical
bne $t3, $zero, ErrorInvalid
slti $t3, $s3, 120                #legal input for lower case characters
bne $t3, $zero, Move
bgt $s3, 119, ErrorInvalid   # illegal input, out of range
addi $sp,$sp,4

#now I iterate again, this time to check for invalid input
Move:
addi $sp, $sp, 1 #iterates
j verify #goes to verification point

#first step of conversion, does the prerequisite work for translation 
initial:
move $a0, $t2  #moves content
addi $t5, $t5, 0  #$t5 has 0 now
add $s0, $s0, $t0  
addi $s0, $s0, -1 #decrement    
#load immediate puts values in registers to be used
li $s4, 3  #each digit
li $s5, 2
li $s6, 1
li $s1, 0

translate:
addi $sp,$sp,-4
lb $s7, 0($sp)   #loads digits
beqz $s7, final  #final conversion step
beq $s7, $t1, final #if branch statement is true, move to final conversion statement
slti $t3, $s7, 58  #checks for less than or equal to 58
bne $t3, $zero, Base  #OK to move forward if $t3 is not null
slti $t3, $s7, 88  #max for upper
bne $t3, $zero, Mari  #OK to go to conversion of upper characters if $t3 is not null
slti $t3, $s7, 120     #max for lower
bne $t3, $zero, Mici #OK to go to conversion of lower characters if $t3 is not null
addi $sp,$sp,4
Base:
addi $s7, $s7, -48  #conversion for regular numbers
j row

Mari:
addi $s7, $s7, -55  #conversion for upper case
j row

Mici:
addi $s7, $s7, -87  #conversion for lower case

row:  #determines which digit needs to be converted
beq $s0, $s4, one  
beq $s0, $s5, two
beq $s0, $s6, three
beq $s0, $s1, last

#first character
one:
li $t6, 35937   #values to multiply by for the power of 3
mult $s7, $t6
mflo $t7
add $t5, $t5, $t7
addi $s0, $s0, -1
addi $sp, $sp, 1  ####################
j translate

#second character
two:
li $t6, 1089   #values to multiply by for the power of 2
mult $s7, $t6
mflo $t7
add $t5, $t5, $t7
addi $s0, $s0, -1
addi $sp, $sp, 1  ###################
j translate

#third character
three:
li $t6, 33   #values to multiply by for the power of 1
mult $s7, $t6
mflo $t7
add $t5, $t5, $t7
addi $s0, $s0, -1
addi $sp, $sp, 1
j translate

#fourth character
last:
li $t6, 1    #values to multiply by for the power of 0
mult $s7, $t6
mflo $t7
add $t5, $t5, $t7
#no more need to go back to translation step


final:                  #final step
li $v0, 1
move $sp, $t5  #moves content to $a0 so it can be printed
syscall

#last system call of the program will end program
end:   #prints result
 li $v0, 10
 syscall

jr $ra
在main中,您将a0(用户输入的号码)保存到0(SP),将ra保存到12(SP),然后拨打电话号码

在数字中,将-4添加到SP。 十次尝试从0(SP)获取字节

我假设您正在尝试从用户字符串中获取第一个字符

  • 由于将-4添加到堆栈中,因此保存在0(SP)中的a0值不是4(SP)

  • 保存的值是指向字符串的指针,因此从指针加载字节:

  • 因此,改变:

    lb $t8, 0($sp)
    


    这也意味着您不需要在几行之后移动
    $t8,$a0
    ,因此您以
    $t0
    =0结束。现在你需要弄清楚原因。在MARS中,您可以向前和向后单步执行代码,设置断点,查看寄存器值和内存内容。您需要使用这些功能来交叉检查代码的实际行为与应该执行的操作。谢谢!我试试看。
    lw $a0, 4($sp)
    lb $t8, 0($a0)