COMP2421 Computer Organization 2019/20 Semester 1
Lab 5 MIPS Assembly Language Basics III
In this lab, how ¡°procedures/sub-routines/functions¡± can be implemented in assembly language will be introduced.
Jump-And-Link
Copyright By PowCoder代写 加微信 powcoder
The following is an example program which uses a subroutine to print ¡°Hello World!¡± for 10 times.
# A program prints “Hello World” by calling a “subroutine”.
.globl main
add $t0, $0, $0
jal printMessage
add $t0, $t0, 1
bne $t0, 10, p1
li $v0, 10
# initialize $t0 to zero
# print “Hello World!”
# exit program
# Sub-Routine to print the Hello message
printMessage:
la $a0, str
# get the string
# print message
str: .asciiz “Hello World!\n”
jal first stores the return address in the $ra register and jumps to the address indicated by printMessage in the program. After completing printMessage, jr will jump back to the address, stored in $ra.
COMP2421 Computer Organization 2019/20 Semester 1
Parameter Passing
The following example program illustrates how parameters can be passed to a subroutine. It shows the steps of converting a number from base-10 to base-2.
###################################################################################### #
# Given an integer, show the computation results (Quotient and Remainder)
# by successively dividing it by 2 for 10 times.
# Procedure:
# 1. Print the message “Enter an integer:”
# 2. Read the input integer from the console to a register.
# 3. Divide it by 2 for ten times (and show the remainder and Quotient in each step). # ######################################################################################
.asciiz “Enter an integer: ”
.asciiz “\n”
.globl main
Remainder: ”
Quotient: ”
# Step 1: Print the prompt message using system call 4
li $v0, 4 # and I/O code into $v0
syscall # execute the syscall to perform input/output via the console
# Step 2: load integer from memory and print it to console using a loop
move $t0, $v0
# Step 3: print a newline
la $a0, cr
li $v0, 4 syscall
# call syscall 5 to read the integer
# after the call, the number is stored in $v0
# $t0 stores the input integer
str1 # load string address into $a0
# Step 4: divide the input number by 2 for ten times
li $t1, 10
div $t0, $t2
# $t1 — loop counter li $t2, 2
# divide $t0 by 2
# $t0 stores quotient
COMP2421 Computer Organization
2019/20 Semester 1
move $a0, $t0
move $a1, $t3
jal print_qr
add $t1, $t1, -1
bnez $t1, loop
#End of program
li $v0, 10
# $t3 stores remainder
# first parameter: quotient
# second parameter: remainder
# Subroutine: print_qr(quotient, remainder)
# decrease loop counter by 1
# if $t1 !=0, jump to loop
# syscall code 10 for terminating the program
# Sub-Routine to print the Remainder and Quotient
# Procedure: print_qr
# Input: $a0-Quotient, $a1-remainder
move $s0, $a0
move $s1, $a1
# print remainder
la $a0, r_str
move $a0, $s1
# print Quotient
la $a0, q_str
move $a0, $s0
# print a newline
la $a0, cr
# $s0 for Quotient
# $s1 for Remainder
# load string address
# call syscall 4 to print the string to the console
# load string address
# call syscall 4 to print the string to the console
COMP2421 Computer Organization 2019/20 Semester 1
The following program copies a string to a set of memory locations.
# Program copies a string from [A] to [B], character by character.
outputAmsg: .asciiz “\n String A: ”
outputBmsg: .asciiz “\n String B: ”
A: .asciiz “The string to be copied.\n”
B: .space 100
#Start of the main program
.globl main
jal strcpy
# Output string A:
4 outputAmsg
# B is the first parameter (destination)
# A is the second parameter (source)
# jump to “strcpy” to copy characters from source
# print_str (system call 4)
# output “\n String A:”
# print_str
# output the string A
# print_str (system call 4)
# output “\n String B:”
# print_str
# output the string B
# Output string B:
4 outputBmsg
# End of program
li $v0, 10
# Subroutine – Copy string from [A] to [B]
# Function strcpy
add $s0, $0, $0
# $s0 holds the position of characters
# get address of current character (source) and
# store it in $t1
# $t2 = value of current character (source)
# get address of current character (destination)
# and store it in $t3
add $t1, $a1, $s0
lb $t2, 0($t1)
add $t3, $a0, $s0
COMP2421 Computer Organization 2019/20 Semester 1
sb $t2, 0($t3)
add $s0, $s0, 1
bne $t2, $0, L1
# save $t2 to current position of destination
# move to next character
# if $t2 != 0 (null), go to L1
# return to main program
Nested Function Call
Since there is only one $ra register, repeated jal call will overwrite previous return addresses if functions are called in a nested manner. Suppose a series of function calls are performed as below:
main call return
Function A
Function B return
It is better to store the return address to a stack in the main memory before calling a function. A stack is a data structure which stores data in the memory in ¡°Last In First Out¡± (LIFO) manner. A stack pointer has to be maintained to indicate the top of the stack. In main memory, the bottom of the stack is represented by a higher address.
Higher address
Lower address
In A, before B is called, the return address of A has to be stored in the stack. In assembly program, $sp has to be properly managed by programmer. Read the following example:
Stack pointer ($sp)
COMP2421 Computer Organization 2019/20 Semester 1
# Program that demonstrates nested function call
outputMain: .asciiz “\n I am in main. ”
outputAmsg: .asciiz “\n I am in A. ”
outputBmsg: .asciiz “\n I am in B. ”
.globl main
la $a0, outputMain
la $a0, outputMain
li $v0, 10
la $a0, outputAmsg
subu $sp, $sp, 4
sw $ra, ($sp)
lw $ra, ($sp)
addu $sp, $sp, 4
la $a0, outputAmsg
la $a0, outputBmsg
# exit the program
# point to the place for the new item
# store $ra as the new top
# restore the return address
# “remove” the return address from the stack
[Question: Should the parameters and local variables (if any) be passed to the stack before a function call? Why? and how?]
COMP2421 Computer Organization
2019/20 Semester 1
[Exercise]
Write a program to perform the following matrix calculation:
Here are the steps:
1. Read integers (a, b, c, d, x, and y) input by the user.
2. Perform the calculation and store the results in i and j wherei = (ax + by)andj = (cx + dy).
Write two subroutines: ¡°compute_i¡± and ¡°compute_j¡±, by passing the related integers to the function.
3. Print the results, i and j on the console.
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com