So I have two MAL programs that I am getting 2 errors in each of them. I am using xSpim on unix to run this program. I wrote this using the windows version PCSPIM which compiled the program and ran it flawlessly. But when I tried to run it using XSPIM on unix there are errors.
The Error is in the Last 2 lines of this program or Lines 276 and 277.
spim: (parser) Unknown character on line 276 of file p5a.mal
li $v0, 10
spim: (parser) syntax error on line 277of file P5a.mal
syscall
#This program is going to take an input positive integer. The number is assumed to be
#greater than zero. The program will find the Highest power of 2 that Divides the given
#value, no of 1's in binary representation of the given number and sum of digits.
#All the variables are going to be declared in the data section.
.data
#The messages which are going to be printed out in different situations needs to be
#stored in memory.
Output_MaxDivisor_Message: .asciiz "Highest power of 2 that divides the given value = "
Output_NumberOf1_Message: .asciiz "No. of 1's in the binary representation = "
Output_SumOfDigit_Message: .asciiz "Sum of decimal digits = "
Input_Message: .asciiz "Input value: "
New_Line: .asciiz "\n"
#This variable is going to hold the input integer.
Input_Number: .word 0
#This variable is going to store the power of 2 which will completly divide the input number
Max_Divisor: .word 0
#This variable is going to store the number of 1's in binary representation of the
#input number.
Number_Of_1: .word 0
#This is going to store the sum of digits.
Sum_Of_Digits: .word 0
##
#Now we are going to place our code in the text section.
.text
#This is our main function
main:
#Prompt the user for an input.
la $a0, Input_Message
li $v0, 4
syscall
li $v0,5
syscall
move $t1, $v0
la $a0, New_Line
li $v0, 4
syscall
sw $t1, Input_Number #We are going to keep a copy of the orginal value as we will need it to perform the rest of the tasks.
li $t2, 0 #This is going to contain the maximum value by which this variable is divisible
max_divisor_loop:
and $t3,$t1,0x0001 #We have to check if the first bit is 1 and store the result in $t3.
bnez $t3, max_divisor_loop_end #We are going to terminate the loop as soon as we find a 1
sra $t1,$t1,1 #We will shift the contents of the integer to right by 1 which is equal to dividing the value by 2
add $t2,$t2,1 #We will shift the contents of the divisor by 1 means we multiply it by 2.
b max_divisor_loop
max_divisor_loop_end:
#We will store the value in the memory
sw $t2, Max_Divisor
###
li $t2, 0 #This variable is going to count the number of ones in the variable
number_of_1_loop:
beqz $t1, number_of_1_loop_end #We are going to keep on looping till we check each and every remaining bit of the given value.
and $t3,$t1,1 #Separeate the last bit so that we can check whether it is 0 or 1.
sra $t1,$t1,1 #Shift the number left as we have checked this bit already so no need to check it again.
beqz $t3,number_of_1_loop
add $t2,$t2,1 #If there was a one at that place than we need to increment the count. Means we have detected one more 1 bit.
b number_of_1_loop
number_of_1_loop_end:
sw $t2, Number_Of_1
###
#As we have completly lost the input integer so we will reload it from memory where we kept a copy of the variable to deal
#with such a situation
lw $t1,Input_Number
li $t2, 0 #This variable is going to store the sum of all the digits of the number
li $t5,10 #This will be used to keep on dividing the given value.
sum_of_digit_loop:
beqz $t1, sum_of_digit_loop_end #If the number has already reached zero than we do not need to move further we will Just exit the loop.
div $t1,$t5 #We will divide the number by 10 and add the remained to the sum stored in $t2
mflo $t1 #Load the quotent in $t1
mfhi $t4 #Load the remainder to $t4
add $t2,$t2,$t4 #Add the remainder to the previous sum in $t2
b sum_of_digit_loop #we will jump to the start of the loop
sum_of_digit_loop_end:
#We will store the sum of digits in the varable.
sw $t2, Sum_Of_Digits
#Now we need to print the results as we are going to terminate the program.
#We will print out the number of 1's in the integer.
la $a0, Output_NumberOf1_Message
li $v0, 4
syscall
lw $a0, Number_Of_1
li $v0, 1
syscall
la $a0, New_Line
li $v0, 4
syscall
#Print the max 2's power which is able to completly divde the integer.
la $a0, Output_MaxDivisor_Message
li $v0, 4
syscall
lw $a0, Max_Divisor
li $v0, 1
syscall
la $a0, New_Line
li $v0, 4
syscall
#Print the sum of digits
la $a0, Output_SumOfDigit_Message
li $v0, 4
syscall
lw $a0, Sum_Of_Digits
li $v0, 1
syscall
la $a0, New_Line
li $v0, 4
syscall
exit:
#At the end of our execution we need to halt the system.
li $v0, 10
syscall #This program is going to take an input positive integer. The number is assumed to be
#greater than zero. The program will find the Highest power of 2 that Divides the given
#value, no of 1's in binary representation of the given number and sum of digits.
####
#All the variables are going to be declared in the data section.
.data
#The messages which are going to be printed out in different situations needs to be
#stored in memory.
Output_MaxDivisor_Message: .asciiz "Highest power of 2 that divides the given value = "
Output_NumberOf1_Message: .asciiz "No. of 1's in the binary representation = "
Output_SumOfDigit_Message: .asciiz "Sum of decimal digits = "
Input_Message: .asciiz "Input value: "
New_Line: .asciiz "\n"
#This variable is going to hold the input integer.
Input_Number: .word 0
#This variable is going to store the power of 2 which will completly divide the input number
Max_Divisor: .word 0
#This variable is going to store the number of 1's in binary representation of the
#input number.
Number_Of_1: .word 0
#This is going to store the sum of digits.
Sum_Of_Digits: .word 0
#####
#Now we are going to place our code in the text section.
.text
#This is our main function
main:
#Prompt the user for an input.
la $a0, Input_Message
li $v0, 4
syscall
li $v0,5
syscall
move $t1, $v0
la $a0, New_Line
li $v0, 4
syscall
sw $t1, Input_Number #We are going to keep a copy of the orginal value as we will need it to perform the rest of the tasks.
li $t2, 0 #This is going to contain the maximum value by which this variable is divisible
max_divisor_loop:
and $t3,$t1,0x0001 #We have to check if the first bit is 1 and store the result in $t3.
bnez $t3, max_divisor_loop_end #We are going to terminate the loop as soon as we find a 1
sra $t1,$t1,1 #We will shift the contents of the integer to right by 1 which is equal to dividing the value by 2
add $t2,$t2,1 #We will shift the contents of the divisor by 1 means we multiply it by 2.
b max_divisor_loop
max_divisor_loop_end:
#We will store the value in the memory
sw $t2, Max_Divisor
#####
li $t2, 0 #This variable is going to count the number of ones in the variable
number_of_1_loop:
beqz $t1, number_of_1_loop_end #We are going to keep on looping till we check each and every remaining bit of the given value.
and $t3,$t1,1 #Separeate the last bit so that we can check whether it is 0 or 1.
sra $t1,$t1,1 #Shift the number left as we have checked this bit already so no need to check it again.
beqz $t3,number_of_1_loop
add $t2,$t2,1 #If there was a one at that place than we need to increment the count. Means we have detected one more 1 bit.
b number_of_1_loop
number_of_1_loop_end:
sw $t2, Number_Of_1
#####
#As we have completly lost the input integer so we will reload it from memory where we kept a copy of the variable to deal
#with such a situation
lw $t1,Input_Number
li $t2, 0 #This variable is going to store the sum of all the digits of the number
li $t5,10 #This will be used to keep on dividing the given value.
sum_of_digit_loop:
beqz $t1, sum_of_digit_loop_end #If the number has already reached zero than we do not need to move further we will Just exit the loop.
div $t1,$t5 #We will divide the number by 10 and add the remained to the sum stored in $t2
mflo $t1 #Load the quotent in $t1
mfhi $t4 #Load the remainder to $t4
add $t2,$t2,$t4 #Add the remainder to the previous sum in $t2
b sum_of_digit_loop #we will jump to the start of the loop
sum_of_digit_loop_end:
#We will store the sum of digits in the varable.
sw $t2, Sum_Of_Digits
#Now we need to print the results as we are going to terminate the program.
#We will print out the number of 1's in the integer.
la $a0, Output_NumberOf1_Message
li $v0, 4
syscall
lw $a0, Number_Of_1
li $v0, 1
syscall
la $a0, New_Line
li $v0, 4
syscall
#Print the max 2's power which is able to completly divde the integer.
la $a0, Output_MaxDivisor_Message
li $v0, 4
syscall
lw $a0, Max_Divisor
li $v0, 1
syscall
la $a0, New_Line
li $v0, 4
syscall
#Print the sum of digits
la $a0, Output_SumOfDigit_Message
li $v0, 4
syscall
lw $a0, Sum_Of_Digits
li $v0, 1
syscall
la $a0, New_Line
li $v0, 4
syscall
exit:
#At the end of our execution we need to halt the system.
li $v0, 10
syscall
And My 2ns program is going to read a single line of words and than analyze it. It will
find the longest and shortest word in the line. It will print this information on
the screen at the end of the function.
The 2 Errors are on line 361 and 372.
spim: (parser) Unknown character on line 361 of file P5b.mal
Function_Strncpy_End:
spim: (parser) syntax error on line 372 of file P5b.mal
jr $ra # return.
#This program is going to read a single line of words and than analyze it. It will
#find the longest and shortest word in the line. It will print this information on
#the screen at the end of the function.
#####
#All the variables are going to be declared in the data section.
.data
#This is going to store the length of the smallest word in the line. As the smallest
#number would be 1 so we start from 0 to accomodate this case
Max_Word_Length: .word 0
#This is going to store the length of longest word. As the maximum possible word length
#is 80 so we start from something greater than that
Min_Word_Length: .word 81
Max_Word: .space 80 #This is going to store the longest word.
Min_Word: .space 80 #This is going to store the shortest word.
Input_Line: .space 80 #This is going to be used to store the input string
#The messages which are going to be printed out in different situations also need to
#be stored in memory.
Output_Error_Message: .asciiz "The line does not contain any word.\n"
Output_NumberOfnonWhiteSpaceChar_Message: .asciiz "No. of non-whitespace characters: "
Output_NumberOfWords_Message: .asciiz "No. of words: "
Output_MaxWordLength_Message: .asciiz "Maximum length of a word: "
Output_MinWordLength_Message: .asciiz "Minimum length of a word: "
Output_MaxWord_Message: .asciiz "Word of maximum length: "
Output_MinWord_Message: .asciiz "Word of minimum length: "
Input_Message: .asciiz "Input: "
NewLine: .asciiz "\n"
#######
#Now we are going to place our code in the text section.
.text
#Our main program starts from here.
main:
#Print out a request to user to input a line.
la $a0,Input_Message
li $v0, 4
syscall
#Now we will read a line of words from the user
la $a0,Input_Line
#This will indicate the buffer length, so at the most 80 characters including '\0'
# will be written to the buffer.
li $a1, 80
li $v0, 8
syscall
#Now we will initiailize all our variables.
li $s0,0 #It is going to store the number of words
li $s1,0 #It is going to store the number of nonwhitespace_Char
la $s3, Input_Line #It is going to be our loop varaible
sw $0,Max_Word_Length #We need to initialize it to 0(In other words an impossible value)
li $t0,81
sw $t0,Min_Word_Length #We need to initialize it to 81 (In other words an impossible value)
Analyze_Line_Loop:
#Check if we have reached the end of the loop. that is we encountered the '\0'
#character. In that case we sill simply stop our analysis and print out the results.
lb $t0,($s3)
beqz $t0,Analyze_Line_Loop_End
#Call the detect_Word function. This function will assume that the address passed is
#the start of the word. It will return the length of the word in case the word did
#start from this place otherwise it will simply return 0 meaning no word found at this
#location.
move $a0,$s3
jal Function_Detect_Word
#Check if we did found a word. In that case we are going to jump to Word_Found. Otherwise
#we are simply going to increment the pointer and jump back to start of the loop
bnez $v0,Word_Found
addu $s3,$s3,1
b Analyze_Line_Loop
Word_Found:
#If we found a word than we will increment number of words and nonspace character counts
add $s0,$s0,1
move $s4,$v0
add $s1,$s1,$s4
#Now we need to check if the word detected is longer than any of the previous words
lw $t3,Max_Word_Length
bgt $v0,$t3,Update_Max
b Check_Min
Update_Max:
#We will call our strncpy function. Which copies the specified number of characters
#from source string into the destination address and appends a '\0' character at the
#end to make it a null terminated string.
la $a0,Max_Word #Destination address
move $a1,$s3 #Source address
move $a2,$s4 #Length of the string to be copied
jal Function_Strncpy
#We will also update the Max_Word_Length
sw $s4,Max_Word_Length
Check_Min:
#Now we need to check if the word detected is smaller than any of the previous words.
#If it indeed is than we will update our variables.
lw $t3, Min_Word_Length
bgt $t3,$s4, Update_Min
b Increment_Pointer
Update_Min:
#We will call our strncpy function. Which copies the specified number of characters
#from source string into the destination address and appends a '\0' character at the
#end to make it a null terminated string.
la $a0,Min_Word #Destination address
move $a1,$s3 #Source address
move $a2,$s4 #Length of the string to be copied
jal Function_Strncpy
#We also need to update the Min_Word_Length variable
sw $s4,Min_Word_Length #Update the Min word length
Increment_Pointer:
#Now we need to increment our pointer, so that we can search the next word. The
#increment is of the equal to the length of the word detected. We will jump back
#to the top of the loop to start analyzing the input string again.
addu $s3,$s3,$s4
b Analyze_Line_Loop
Analyze_Line_Loop_End:
#If we were unable to detect even a single word than that means the line only
#contained space characters. So we will print the error messages and than jump
#to the end of the function. However if that is not the case than we will jump
#to Print_Results to print out all the results.
bnez $s1,Print_Results
#We need to print the error message that the string was completly empty
la $a0,Output_Error_Message
li $v0, 4
syscall
#We will jump to the end of te function and call the halt system call.
b Main_End
Print_Results:
#If we were able to find some resutls than we are going to print out the resutls.
#Print the number of nonspace characters.
la $a0,Output_NumberOfnonWhiteSpaceChar_Message
li $v0, 4
syscall
move $a0, $s1
li $v0, 1
syscall
la $a0,NewLine
li $v0, 4
syscall
#Print the number of words in the line.
la $a0,Output_NumberOfWords_Message
li $v0, 4
syscall
move $a0, $s0
li $v0, 1
syscall
la $a0,NewLine
li $v0, 4
syscall
#Print the length of the longest word.
la $a0,Output_MaxWordLength_Message
li $v0, 4
syscall
lw $a0,Max_Word_Length
li $v0, 1
syscall
la $a0,NewLine
li $v0, 4
syscall
#Print the length of the smallest word.
la $a0,Output_MinWordLength_Message
li $v0, 4
syscall
lw $a0,Min_Word_Length
li $v0, 1
syscall
la $a0,NewLine
li $v0, 4
syscall
#Print the longest word
la $a0,Output_MaxWord_Message
li $v0, 4
syscall
la $a0,Max_Word
li $v0, 4
syscall
la $a0,NewLine
li $v0, 4
syscall
#Print the smallest word
la $a0,Output_MinWord_Message
li $v0, 4
syscall
la $a0,Min_Word
li $v0, 4
syscall
la $a0,NewLine
li $v0, 4
syscall
Main_End:
#At the end of our execution we need to halt the system.
li $v0,10
syscall
#######
#This function is going to check if this function is a space, tab, newline or carrage return character. If yes than
#it will return a value 1 else it will return a value 0
Function_Check_Char:
#We need to store the Callee store register to ensure that they are untouched.
#They are going to be pushed on the stack.
subu $sp, $sp, 32 # frame size = 32,
sw $ra, 28($sp) # preserve the Return Address.
sw $fp, 24($sp) # preserve the Frame Pointer.
sw $s0, 20($sp) # preserve $s0.
sw $s1, 16($sp) # preserve $s1.
sw $s2, 12($sp) # preserve $s2.
sw $s3, 8($sp) # preserve $s3.
sw $s4, 4($sp) # preserve $s4.
sw $s5, ($sp) # preserve $s5.
addu $fp, $sp, 32 # move Frame Pointer to base of frame.
li $t2,1 #This is going to store the return value
move $t0, $a0 #Move the value from $a0 to $t0
beq $t0,' ', Function_Check_Char_End #Is it a space
beq $t0, 10, Function_Check_Char_End #Is it '\n'
beq $t0, 13, Function_Check_Char_End #Is it '\r'
beq $t0, 9, Function_Check_Char_End #Is it '\t'
li $t2,0
Function_Check_Char_End:
#We will copy the results to $v0, so that it could be checked by the caller.
move $v0,$t2
#Before we go back we need to restore all the registers
lw $ra, 28($sp) # restore the Return Address.
lw $fp, 24($sp) # restore the Frame Pointer.
lw $s0, 20($sp) # restore $s0.
lw $s1, 16($sp) # restore $s1.
lw $s2, 12($sp) # restore $s2.
lw $s3, 8($sp) # restore $s3.
lw $s4, 4($sp) # restore $s4.
lw $s5, ($sp) # restore $s5.
addu $sp, $sp, 32 # restore the Stack Pointer.
jr $ra # return.
#######
#This function is going to get the address of the start of the word. It will keep on looping till the time it
#reaches the end of the string or it detects a space character. It will than return the number of characters from
#start till the end of the word.
Function_Detect_Word:
#We need to store the Callee store register to ensure that they are untouched.
#They are going to be pushed on the stack.
subu $sp, $sp, 32 # frame size = 32,
sw $ra, 28($sp) # preserve the Return Address.
sw $fp, 24($sp) # preserve the Frame Pointer.
sw $s0, 20($sp) # preserve $s0.
sw $s1, 16($sp) # preserve $s1.
sw $s2, 12($sp) # preserve $s2.
sw $s3, 8($sp) # preserve $s3.
sw $s4, 4($sp) # preserve $s4.
sw $s5, ($sp) # preserve $s5.
addu $fp, $sp, 32 # move Frame Pointer to base of frame.
move $s0,$a0 #Move the address of the string to $S0 so that we can strat processing.
li $s1,0 #This is going to store the number of characters present in this word
Check_Char_Loop:
#We will call the Check_Char function to see if the character is not a space char. If it
#was indeed a space character than that means we reached the end of the word and we need
#to exit the function.
lb $a0,($s0)
jal Function_Check_Char
bnez $v0,Check_Char_Loop_End
#If it is still not the end of the char than we will inrement the pointers and check the
#next char.
addu $s0,$s0,1
add $s1,$s1,1
b Check_Char_Loop
Check_Char_Loop_End:
#we need to return the results in $v0, so we will copy the length of the word in $v0
move $v0,$s1
Function_Detect_Word_End:
#Before we go back we need to restore all the registers
lw $ra, 28($sp) # restore the Return Address.
lw $fp, 24($sp) # restore the Frame Pointer.
lw $s0, 20($sp) # restore $s0.
lw $s1, 16($sp) # restore $s1.
lw $s2, 12($sp) # restore $s2.
lw $s3, 8($sp) # restore $s3.
lw $s4, 4($sp) # restore $s4.
lw $s5, ($sp) # restore $s5.
addu $sp, $sp, 32 # restore the Stack Pointer.
jr $ra # return.
########
#This function is going to get the address of the start of the word. It will keep on looping till the time it
#reaches the end of the string or it detects a space character. It will than return the number of characters from
#start till the end of the word.
Function_Strncpy:
#We need to store the Callee store register to ensure that they are untouched.
#They are going to be pushed on the stack.
subu $sp, $sp, 32 # frame size = 32,
sw $ra, 28($sp) # preserve the Return Address.
sw $fp, 24($sp) # preserve the Frame Pointer.
sw $s0, 20($sp) # preserve $s0.
sw $s1, 16($sp) # preserve $s1.
sw $s2, 12($sp) # preserve $s2.
sw $s3, 8($sp) # preserve $s3.
sw $s4, 4($sp) # preserve $s4.
sw $s5, ($sp) # preserve $s5.
addu $fp, $sp, 32 # move Frame Pointer to base of frame.
move $t1,$a0 #Destination address
move $t2,$a1 #Source address
move $t3,$a2 #Number of bytes to copy
Copy_Loop:
lb $t4, ($t2) #Load data from one string into $t4
sb $t4,($t1) #Store the data into the other string
addu $t1,$t1,1 #Increment the address to point to the next location
addu $t2,$t2,1 #Increment the address to point to the next location
sub $t3,$t3,1 #decement the counter
bnez $t3,Copy_Loop
Copy_Loop_End:
sb $0,($t1) #Make it a null terminated string
Function_Strncpy_End:
#Before we go back we need to restore all the registers
lw $ra, 28($sp) # restore the Return Address.
lw $fp, 24($sp) # restore the Frame Pointer.
lw $s0, 20($sp) # restore $s0.
lw $s1, 16($sp) # restore $s1.
lw $s2, 12($sp) # restore $s2.
lw $s3, 8($sp) # restore $s3.
lw $s4, 4($sp) # restore $s4.
lw $s5, ($sp) # restore $s5.
addu $sp, $sp, 32 # restore the Stack Pointer.
jr $ra # return.
Can Anyone give me direction on correcting these errors?