cabosun 0 Newbie Poster

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?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.