CS201 Lab: SPIM Procedure Calls


        In CS110, you have learned how to write user defined functions using C++.
        In CS201, you can define similar functions using SPIM.  
        This lab focuses on implementing procedure/function calls in SPIM.

Procedure Calls

In this section, we are going to examine the code used to implement procedure and function calls. Procedures are the most important technique for structuring programs.

In C++, a function is called by its name with required arguments. When a function is called, the system will execute the function. When the function is finished, it returns a value to the calling function and the execution continues from the next statement right after the function call.

In SPIM, a function/procedure can be called by the code/control of jal functionname/procedurename. The code/control jr $ra can be used at the end of a procedure to return the control back to the statement right after the function/procedure call. When jal functionname/procedurename is executed, $ra is used to hold the return address (PC+4).

The following picture illustrates functions implemented in SPIM.

Passing Parameters

The first four parameters of a procedure are passed in argument registers $a0, $a1, $a2, $a3. Additional parameters are passed using the stack. $v0 and $v1 are used to store returned values. The following demonstrates procedure calls and passing and returning values from or to the calling function.
	 
##
##	Program name:	sum.s 
##
## 	The program will prompt the user to enter an integer N.
##	A user defined function "sumup" will be called.

##	The function "sumup" will calculate the sum of 
##	the integers from 1 to N (N will be passed to
##	the function "sumup" in register $a0, and 
##	the sum will be returned in $v0).

##
##	The program will print out the final result sum.
##		
##
##		$v0 - reads in an integer
##		$t0 - holds the sum 
## 		$a0 - points to strings to be printed 
##		    - also used to pass N to "sumup" 
##

#################################################
#                                               #
#               text segment                    #
#                                               #
#################################################

	.text
	.globl __start
__start:		# execution starts here

	la $a0,prompt1	# print prompt on terminal
	li $v0,4 	# system call to print
	syscall		# out a string

	
	
	li $v0,5	# syscall 5 reads an integer 
	syscall         

	move $a0, $v0	# copy the integer to $a0

	jal sumup	# procedure/function call

	move $t0, $v0	# copy the sum to $t0

	
	la $a0,ans1	# print string before the sum
	li $v0,4
	syscall 

	move $a0,$t0	# print the sum
	li $v0,1
	syscall

	
	la $a0,endl	# syscal to print out
	li $v0,4	# a new line
	syscall 

	li $v0,10	# exit
	syscall		# Bye!

############################################################
##
##	The function "sumup" will calculate the sum of 
##	the integers from 1 to N (N will be passed to
##	the function "sumup" in register $a0, and 
##	the sum will be returned in $v0).
##
############################################################

sumup:
	move $v0, $0		# Initialize the sum to 0
	#li  $v0, 0   		# OR initialize it this way

loop:	add $v0, $v0, $a0	# $v0 = $v0 + $a0
	addi $a0, $a0, -1	# $a0 = $a0 - 1
	bnez $a0, loop		# branch to loop if $a0 != 0

	jr $ra			# return to the calling function



#################################################
#  						#
#               data segment			#           
#						#
#################################################

        .data
	
	prompt1:	.asciiz "Please enter an integer:  "
	
	ans1:		.asciiz "The sum is "
   	
	endl:		.asciiz "\n"	   

##
## 	end of file sum.s

Another example:


##
## 	The program --- Is-vowel.s will check if an entered character is a vowel.
##
##		- It will ask the user for a letter (character),
##		  
##		- then call a procedure ("vowelp") to check if it is a vowel.
##		- It will return a value to the calling function, 
##		  0 means no, and 1 means yes,
##		- and then print a message from the calling program.
##		
##		$v0 - used for syscalls
##		    - holds 0 or 1 after the call to "vowelp"
##		$t0 - holds the returned value from the procedure call
## 		$a0 - points to strings to be printed 
##		    - also used to pass a letter to "vowelp" 
##
##

#################################################
#						#
#               text segment			#
#						#
#################################################

	.text
	.globl __start
__start:                # execution starts here

	la $a0,prompt1  # print prompt on terminal
	li $v0,4        # system call to print
	syscall         # out a string

	la $a0,letter
	li $a1,5
	li $v0, 8	# syscall 8 reads string/letter
	syscall

	la $a1, letter	# prepare for passing a letter to the procedure
	lb $a0,($a1)

	jal vowelp	# procedure call

	move $t0,$v0	# save the value returned from the procedure call

	beqz $t0, NotVowel
	

	la $a0,ans1	# syscall to print out
	li $v0,4	# the message - is vowel
	syscall 
	j End

NotVowel:
	la $a0,message	# syscall to print out
	li $v0,4	# the message - not vowel
	syscall 

End:	la $a0,endl	# syscall to print out
	li $v0,4	# a new line
	syscall 

	li $v0,10
	syscall		# Bye!

##############################################################
## Define the procedure vowelp
##############################################################

vowelp:

	beq $a0,'a',yes
	beq $a0,'A',yes
	beq $a0,'e',yes
	beq $a0,'E',yes
	beq $a0,'i',yes
	beq $a0,'I',yes
	beq $a0,'o',yes
	beq $a0,'O',yes
	beq $a0,'u',yes
	beq $a0,'U',yes
	li $v0, 0	# assign 0 to $v0 
	jr $ra
yes:	li $v0, 1	# assign 1 to $v0
	jr $ra
	

#################################################
#						#
#               data segment			#
#						#
#################################################

        .data
	letter:		.space 5
	prompt1:	.asciiz "Enter a character: "
	
	message:	.asciiz "The character entered is not a vowel."
	ans1:		.asciiz "The character entered is a vowel. "
	endl:		.asciiz "\n"	   

##
## 	end of file Is-vowel.s


Lab Assignment


Copyright: Department of Computer Science, University of Regina.