MIPS code using stack produces a recursion error - recursion

In this assignment I have to convert any given number from base 33 (1-9, A-W, and a-w) to base 10. If the input is empty, the message "Input is empty" is displayed. If input is anything else than numbers or letters A-W, output will be: "Input is invalid". This program must use stack and recursion.
I wrote my program without stack and it was working. I am now trying to transfer that into a program that uses stack but am getting the message "Input is empty", regardless of what I input.
Here is my MIPS code:
############### 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

In main, you save a0 (the user entered number) to 0(SP), and ra to 12(SP), then call Number.
In number, you add -4 to SP.
Ten attempt to get a byte from 0(SP)
I am assuming you are trying to get the first character from the user string ?
Since you added -4 to the stack, the a0 value you saved in 0(SP) is not at 4(sp).
The value you saved is the pointer to the string, so doing a load byte from the pointer:
So change:
lb $t8, 0($sp)
to
lw $a0, 4($sp)
lb $t8, 0($a0)
Which also means you don't need the move $t8, $a0 a couple of lines later

Related

Fibonacci recursion function in Mips

I am trying to pratice how recursion works in Mips. So I tried to write a fibonacci function fib.
At first I had addi $a0, $a0, n to write a general solution, but I thought that if I want to check my results in Qtspim , maybe i need to add a real number as an argument. I do not want a full answer , if the thought behind the code is wrong, but some help in order to run it in Qtspim, and find my mistakes (logic mistakes) on my own
This is my code:
.globl main
.text
main:
addi $a0, $a0, 4
fib:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1
beq $t0, 1, L2 #if n<1
beq $a0, 1, L2 # if n=1
beq $t0, 0, L1 # if n>1
#what to do when n<=1
L2:
addi $v0, $v0, 1
jr $ra
#what to do when n>1
L1:
addi $a0, $a0, -1
jal fib
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
lw $t1, 0($v0)
add $v0, $t1, $v0
jr $ra
li $v0,10
syscall
I get an error message as such:
Bad address in data/stack read: 0x00000000
.text
main:
addi $a0, $a0, 4
#### you've place fib inline inside main,
#### you should have all of main here, and "call" fib using jal instruction
#### and the syscall for exit goes up here as well
fib:
addi $sp, $sp, -8 # you will want one more word of stack space
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 1 # i would have use 2 here instead of 1
beq $t0, 1, L2 #if n<1 # this is ok, but better to use bne $t0, $0, L2
beq $a0, 1, L2 # if n=1 # and then this would not be needed
beq $t0, 0, L1 # if n>1 # this doesn't need to be conditional, if the program reaches here then L1 is the thing to do next.
#what to do when n<=1
L2:
addi $v0, $v0, 1 # here you want to return just 1 not v0+1
jr $ra
#what to do when n>1
L1:
addi $a0, $a0, -1
jal fib # fib(n-1), good
lw $a0, 0($sp) # this reloads $a0 the original n
lw $ra, 4($sp)
addi $sp, $sp, 8
lw $t1, 0($v0) # after a call to fib $v0 holds fib(n)
# an integer value but you're treating it like a pointer and dereferencing it
add $v0, $t1, $v0 # here doing fib(n-1) + n
# you want fib(n-1) + fib(n-2) instead
# so you're missing a fib(n-2)
jr $ra
li $v0,10 # this is part of main, so move it to where main is
syscall # realize that code located here is unreachable (aka dead)
# anything after an unconditional branch (here the jr $ra just above)
# and without a label is very suspicious as unreachable
update , some improved (i hope ) code
.globl main
.text
main:
addi $a0, $a0, 4
jal fib
li $v0, 10
syscall
fib:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
slti $t0, $a0, 2
beq $t0, 1, L2
#what to do when n<=1
L2:
addi $v0, $v0, 1
jr $ra
#what to do when n>1
L1:
addi $a0, $a0, -1 # a0 -> n-1
jal fib # fib(n-1)
lw $a0, 0($sp) #load word from memory adress 0($sp) to register $a0
lw $ra, 4($sp) #load word from memory adress 4($sp) to register $ra
addi $sp, $sp, 8
add $t1, $zero, $v1 # in register $t1 store current $v1
add $v0, $t2, $v0 # v0_ n+1 =v0 _n + v0_n-1
add $t2, $t1, $zero # in $t2 save the previous value of v1
.data
prompt: .ascii "Fibonacci Program\n"
.asciiz "Enter N value: "
results: .asciiz "\nFibonacci of N = "
n: .word 0
answer: .word 0
.text
.globl main
.ent main
main:
# Read n value from user
li $v0, 4 # print prompt string
la $a0, prompt
syscall
li $v0, 5 # read N (as integer)
syscall
sw $v0, n
# Call Fibonacci function.
lw $a0, n
jal fib
sw $v0, answer
# Display result
li $v0, 4 # print prompt string
la $a0, results
syscall
li $v0, 1 # print integer
lw $a0, answer
syscall
# Done, terminate program.
li $v0, 10 # terminate
syscall # system call
.end main
# Fibonacci function
# Recursive definition:
# = 0 if n = 0
# = 1 if n = 1
# = fib(n-1) + fib(n-2) if n > 2
# Arguments
# $a0 - n
# Returns
# $v0 set to fib(n)
.globl fib
.ent fib
fib:
subu $sp, $sp, 8
sw $ra, ($sp)
sw $s0, 4($sp)
move $v0, $a0 # check for base cases
ble $a0, 1, fibDone
move $s0, $a0 # get fib(n-1)
sub $a0, $a0, 1
jal fib
move $a0, $s0
sub $a0, $a0, 2 # set n-2
move $s0, $v0 # save fib(n-1)
jal fib # get fib(n-2)
add $v0, $s0, $v0 # fib(n-1)+fib(n-2)
fibDone:
lw $ra, ($sp)
lw $s0, 4($sp)
addu $sp, $sp, 8
jr $ra
.end fib

Mips Recursive Assignment

I hope everyone is okay in these covid-19 times. I am working on an assignment and I'm hoping someone could point out where I'm going wrong. I'm taking in a number in a MIPS program that will be put in a recursive function that returns the following:
Guidelines are:
The recursive function accepts a single positive integer as an input argument and is defined as:
recurse(n) = 1 if n=0
recurse(n) = n * Recurse(n-1) + 1 if n >0
My recursing is going alright, but I feel like I'm getting lost in the returns when the function unwinds. I'm also pretty sure that a lot of what I'm doing might look very messy as I'm a novice with MIPS. Here is my version:
Here is my code:
PRINT_STRNG = 4
PRINT_INT = 1
PRINT_CHAR = 11
READ_CHAR = 12
READ_STRNG = 8
READ_INT = 5
TERMINATE = 10
NEWLINE = 10
.data
prompt1: .asciiz "\nPlease enter a decimal integer between 1 and 12 (or 0 to stop): "
terminating: .asciiz "\nTerminating!"
recursing: .asciiz "recursing "
returning: .asciiz "returning "
newLine: .asciiz "\n"
.text
main:
jal clearRegs
li $t0, 4
jal promptNumber
move $a1, $v0
beq $a1, $zero, exit
move $t2, $a1 # $t2 has n
mul $t1, $a1, $t0 # $t1 has the spaces
jal factPlusOne
j main
promptNumber:
# Prompt the user for first decimal
li $v0, PRINT_STRNG
la $a0, prompt1
syscall
# Get the user's first decimal
li $v0, READ_INT
syscall
# Print new line after
li $v0, PRINT_STRNG
la $a0, newLine
syscall
jr $ra
printRecursingSpaces:
# $ra now points to below print spaces
# Prints the spaces before the recursing messages
blez $t1, printRecursing
li $a0, 32
li $v0, 11 # syscall number for printing character
syscall
addi $t1, $t1, -1
j printRecursingSpaces
printReturningSpaces:
# Prints the spaces before the returning messages
blez $t1, printReturning
li $a0, 32
li $v0, 11 # syscall number for printing character
syscall
addi $t1, $t1, -1
j printReturningSpaces
factPlusOne:
# Tests to enter recursion or end recursion
move $s0, $ra
jal printRecursingSpaces
bgtz $a1, recurse
li $t3, 1
jr $s0
recurse:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a1, 0($sp)
addi $a1, $a1, -1
mul $t1, $a1, $t0
jal factPlusOne
lw $v1, 0($sp)
mul $t4, $t3, $v1
addi $t4, $t4, 1 # $t3 has n * Recurse(n-1) + 1
mul $t1, $t4, $t0
jal printReturningSpaces
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
printRecursing:
# Prints the recursing message
li $v0, PRINT_STRNG
la $a0, recursing
syscall
# Print the n
li $v0, PRINT_INT
addi $a0, $a1, 0
syscall
# Prints a new line
li $v0, PRINT_STRNG
la $a0, newLine
syscall
jr $ra
printReturning:
# Prints the returning message
li $v0, PRINT_STRNG
la $a0, returning
syscall
# Print the n
li $v0, PRINT_INT
addi $a0, $t4, 0
syscall
# Prints a new line
li $v0, PRINT_STRNG
la $a0, newLine
syscall
jr $ra
clearRegs:
sub $v0, $v0, $v0
sub $v1, $v1, $v1
sub $a0, $a0, $a0
sub $a1, $a1, $a1
sub $t0, $t0, $t0
sub $t1, $t1, $t1
sub $t2, $t2, $t2
sub $t3, $t3, $t3
sub $t4, $t4, $t4
sub $s0, $s0, $s0
jr $ra
exit:
# Show terminating message and exit program
li $v0, PRINT_STRNG
la $a0, terminating
syscall
li $v0, TERMINATE
syscall
Gonna be hacking at it for the next few hours. I appreciate any assistance and hope everyone is having a good Sunday. Thank you!
I did end up fixing this, I just had to grasp the concept that anywhere you need to save the value of $ra, make a stack variable. Working code below:
PRINT_STRNG = 4
PRINT_INT = 1
PRINT_CHAR = 11
READ_STRNG = 8
READ_INT = 5
TERMINATE = 10
NEWLINE = 10
.data
prompt1: .asciiz "\nPlease enter a decimal integer between 1 and 6 (or 0 to stop): "
terminating: .asciiz "\nTerminating!"
recursing: .asciiz "recursing "
returning: .asciiz "returning "
newLine: .asciiz "\n"
theNumber: .word 0
.text
main:
li $t0, 4
jal promptNumber
lw $a1, theNumber
bgt $a1, 6, main # If >6 is entered
beq $a1, $zero, exit # If 0 is entered
blez $a1, main # If <0 is entered
mul $t1, $a1, $t0 # $t1 has the spaces
jal factPlusOne
jal printReturningSpaces # for the last result
j main
promptNumber:
# Prompt the user for first decimal
li $v0, PRINT_STRNG
la $a0, prompt1
syscall
# Get the user's first decimal
li $v0, READ_INT
syscall
sw $v0, theNumber
# Print new line after
li $v0, PRINT_STRNG
la $a0, newLine
syscall
jr $ra
printRecursingSpaces:
# Prints the spaces before the recursing messages
blez $t1, printRecursing
li $a0, 32
li $v0, 11 # syscall number for printing character
syscall
addi $t1, $t1, -1
j printRecursingSpaces
printReturningSpaces:
# Prints the spaces before the returning messages
blez $t1, printReturning
li $a0, 32
li $v0, 11 # syscall number for printing character
syscall
addi $t1, $t1, -1
j printReturningSpaces
factPlusOne:
# Tests to enter recursion or end recursion, saves $ra
addi $sp, $sp, -4
sw $ra, 0($sp)
jal printRecursingSpaces
lw $ra, 0($sp)
addi $sp, $sp, 4
bgtz $a1, recurse
li $t3, 1
jr $ra
recurse:
# wind up recursion
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a1, 0($sp)
addi $a1, $a1, -1
mul $t1, $a1, $t0
jal factPlusOne
# unwind recursion
lw $v1, 0($sp)
jal printReturningSpaces
mul $t1, $v1, $t0
mul $t3, $t3, $v1
addi $t3, $t3, 1
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
printRecursing:
# Prints the recursing message
li $v0, PRINT_STRNG
la $a0, recursing
syscall
# Print the n
li $v0, PRINT_INT
addi $a0, $a1, 0
syscall
# Prints a new line
li $v0, PRINT_STRNG
la $a0, newLine
syscall
jr $ra
printReturning:
# Prints the returning message
li $v0, PRINT_STRNG
la $a0, returning
syscall
# Print the n
li $v0, PRINT_INT
addi $a0, $t3, 0
syscall
# Prints a new line
li $v0, PRINT_STRNG
la $a0, newLine
syscall
jr $ra
exit:
# Show terminating message and exit program
li $v0, PRINT_STRNG
la $a0, terminating
syscall
li $v0, TERMINATE
syscall

Double Recursion in Assembly works until secondary recursion becomes larger than the base case

I am trying to code a Assembly program that will ask for an integer and perform a recursive function: if n>5 f(n) = n*f(n-1)-f(n-3)+n-23 else n<=5 f(n)=15-2n I managed to get the first instance of recursion of the n*f(n-1)but when it goes for the second recursion of f(n-3) it performs the second portion improperly.
During the calculations, if I input 8 as the integer, the result should be 20 which I get but, when I input anything greater than 8 because then the second recursion hits an integer larger than 5 (the base case) I get an incorrect answer. Basically any input larger than 8 doesn't work
For example the correct answers are:
f(9) = 162
f(10) = 1602
f(11) = 17590
The answers I get
f(9)= 27
f(10)=22
f(11)=23
Here is my code:
```#data declarations: declare variable names used in program, storage allocated in RAM
.data
prompt1: .asciiz "\nEnter an Integer:\n" #Ending Index
message1: .asciiz "\nThe Solution is:\n"
answer: .word 0
#program code is contained below under .text
.text
.globl main #define a global function main
# the program begins execution at main()
main:
la $a0, prompt1 #load address of prompt1
li $v0, 4 #prepare print string
syscall
li $v0, 5 #prepare receive int
syscall
move $a0, $v0
addi $sp, $sp, -4
sw $ra, 0($sp)
jal Function
sw $v0, answer #move returned answer to a new memory
lw $ra, 0($sp)
addi $sp, $sp, 4
la $a0, message1 #load address of message1
li $v0, 4 #prepare print string
syscall
lw $a0, answer
li $v0, 1
syscall
jr $ra
############################################################################
# Procedure/Function Function1
# Description: recursive math function
# parameters: $a0 = value of n,
# return value: $v0 = answer
# registers to be used: $s3 and $s4 will be used.
############################################################################
Function:
addi $sp, $sp, -12 #adjust stack pointer
sw $ra, 8($sp) #save return address
sw $a0, 4($sp) #save n
sw $s0, 0($sp) #save immediate value (used for storing function(n-1))
li $t2, 15
slti $t0, $a0, 6
beq $t0, $zero, GreaterThanFive
LessThanFive:
add $t1, $a0, $zero
add $t1, $t1, $a0
sub $t2, $t2, $t1
move $v0, $t2
j Conclusion
GreaterThanFive:
addi $a0, $a0, -1
jal Function
move $s0, $v0
lw $a0, 4($sp)
addi $a0, $a0, -3
jal Function
lw $a0, 4($sp)
mul $t3, $a0, $s0
sub $t4, $t3, $v0
add $t5, $t4, $a0
addi $t6, $t5, -23
move $v0, $t6
Conclusion:
lw $s1,0($sp) # restore intermediate value
lw $a0,4($sp)
lw $ra,8($sp)
addi $sp,$sp,12 # restore stack
jr $ra #return to caller```

MIPS hermite stack example use

I'm stuck on a stack. I have to call to a function in mips-32 assembly code, in which I have to evaluate a Hermite polynomial just by giving the n and the x as parameters. It must be done using recursion.
I've tried to set 2 base cases H0 and H1, using them both at the same time, but I can't identify the sequence and the pile draw that makes the code clear.
Follows the code:
li $t2,2
recursive_hermite: #H(n,x,___,___)
bge $a0,$t5,more_than_2
#### base
#### case
jr $ra ##<--- this takes us to the operation of the value
more_than_2:
## here you are supposed to store the values on stack
## (such as return address and n values)
addi $a0,$a0,-1 ##you must decrease n (or increase I'm not sure)
jal recursive_hermite ##once they are stored, you just recall
### operations of value
## $f12 must contain the whole value
jr $ra ####this one returns to the main
Does anyone know how to solve this problem?
I see you are in trouble. Judging the way you wrote the question it seems like your assigment is due tomorrow, so we have to work things fast.
You remind me of myself 20 years back, good old times when c++ was just being born and assembly was all the rage. I have heard of those cringy MIPS emulators like QTspim, you should avoid them and work like a real man with some real handy hardware.
Here is my tip: you have to store the partial results of the polinomials tested in every recursion. To do that you have to control time and space, which have to be perfectly balanced like all things should be.
If I was you I would start working in your step by step execution of the program so you can check what the register values are.
It is dangerous to go alone, take this:
.data
#COMPUTER PRINCIPLES UNIVERSITY OF MACANDCHESTER
#PRACTIC 5: HERMITE POLINOMYALS CALCULUS
#JACK ROBERTS II
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:
li $v0, 8
la $a0, userInput
li $a1, 200
syscall
Rid:
#takes care of leading spaces
li $t9, 32 # space
lb $t8, 0($a0)
beq $t9, $t8, Character
move $t8, $a0
j length
Character:
addi $a0, $a0, 1
j Rid
#takes care of length
length:
addi $t0, $t0, 0
addi $t1, $t1, 10
add $t2, $t2, $a0
#itertates through the array
traverse:
lb $s2, 0($a0)
beqz $s2, discovered
beq $s2, $t1, discovered
addi $a0, $a0, 1
addi $t0, $t0, 1
j traverse
#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 $a0, $t2
#go to next verification process
j verify
#Comenzamos a calcular H0
verify:
lb $s3, 0($a0) #loads address here
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
#now I iterate again, this time to check for invalid input
Move:
addi $a0, $a0, 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
#aqui empieza lo bueno
Must:
addi $sp, $sp, -16
sw $ra, 0($sp)
sw $ra, 4($sp)
sw $ra, 8($sp)
sw $ra, 12($sp)
jal Must
ExitMust:
lw $ra,16($sp)
lw $s4, 3($sp)
lw $s5, 2($sp)
lw $s6, 1($sp)
lw $s1, 0($sp)
jr $ra #return
#li $s4, 3 #each digit
#li $s5, 2
#li $s6, 1
#li $s1, 0
translate:
lb $s7, 0($a0) #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
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 $a0, $a0, 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 $a0, $a0, 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 $a0, $a0, 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 $a0, $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
Hope it helps, if you need, ask for further explanation here, its been directly
taken out of my Final grade Work, and in my Masters.
PD: It is licensed under the GPL, so be careful on what you do with it, FBI might be looking for you.
Love :)

Error in MIPS assembler regarding fetch address not being aligned

having some trouble with an assignment, not looking for solution code, just some answers to why I keep encountering this error.
The program asks the user for 10 digits and then displays the resulting sum (using the stack and recursion).
I know from debugging that the read: portion works fine, but I get the error "Runtime exception at 0x0040005c: fetch address not aligned on word boundary 0x00000001". The error refers to the line in summation: lw $t0, 0($a0)
Not sure what is wrong since I only ever increment by 4 bytes. I've checked other similar questions but couldn't find any clarification. Any help would be greatly appreciated.
.data
A1: .space 40
input: .asciiz "please enter a number: "
Str: .asciiz "the sum is: "
.text
main:
li $s1, 0
la $t0, A1
addi $s0, $zero, 0
read:
beq $s1, 10, prep
li $v0, 4
la $a0, input
syscall
li $v0, 5
syscall
sw $v0, ($t0)
addi $t0, $t0, 4
addi $s1, $s1, 1
j read
prep:
la $a0, A1
addi $a1, $a0, 40
jal summation
summation:
subi $sp, $sp, 8
sw $ra, 4($sp)
lw $t0, 0($a0)
sw $t0, 0($sp)
sgt $t1, $a0, $a1
beq $t1, $zero, L1
addi $v0, $zero, 0
addi $sp, $sp, 8
jr $ra
L1:
addi $a0, $a0, 4
jal summation
lw $a0, 0($sp)
lw $ra 4($sp)
addi $sp, $sp, 8
add $v0, $a0, $v0
jr $ra

Resources