sections in this module | City
College of San Francisco - CS270 Computer Architecture Module: MIPS-IV (Procedures) |
module list |
Problems-Procedures
The
code for each of these problems is in the online/mipsIV directory. The
code no longer uses syscalls. Instead they use the functions from the
util.s package detailed in the SupportFunctions PDF file.
This first function is a slight modification from its counterpart in
the mipsIII problems - arradd.s. In this version, a function is called
to do the addition so that arradd() is not a leaf function.
arradd.s
int arradd(int result[], int arr1[], int arr2[], int nelem)
This function adds two arrays, placing the sum of each corresponding element in a third (result) array. It uses another function add, which adds two ints. We will see how silly this is in assembler, but, remember, a simple straightforward translation of some integer array class with a member function that adds two elements could be similar. It doesn't look bad in higher-level code, but it is very different in assembler.
First, add1.s is a leaf function that simply adds together two integers. It would be called like
result[index] = add1(arr1[index],arr2[index]);
#
# add1.s
#
# int add1(int,int);
# (so named as MARS reserves
instruction names)
#
.text
.globl
add1
add1:
add
$v0,$a0,$a1
jr $ra
Now the code for arradd:
#
# arradd.s - add two arrays
and store
# the sums
of each pair of elements
# in a
parallel third array
#
# int arradd(int
*result, int *arr1, int *arr2, int nelem);
#
# returns 0 (fail) iff
one of result, arr1 or arr2 is NULL
#
.text
.globl
arradd
arradd:
# uses one S register and needs room for ra and its arguments.
addiu $sp,$sp,-24
sw $a3,36($sp) # home all of the arg regs
sw $a2,32($sp)
sw $a1,28($sp)
sw $a0,24($sp)
sw $ra,20($sp) # save return address
sw $s0,16($sp) # to keep index in register
li
$v0,1 # default failure
status
# fail if
any pointer is NULL or if nelems is <= 0
beq $a0,$zero,.Larrbad
beq $a1,$zero,.Larrbad
beq $a2,$zero,.Larrbad
ble $a3,$zero,.Larrbad
# finally
ready to start
li
$s0,0 # index
.Larrloop:
beq $s0,$a3,.Larrdone # if
index == nelems we are done
sll $t4,$s0,2 # convert
index to nbytes
addu $t0,$a1,$t4 # &arr1[index]
lw $a0,0($t0) # arr1[index]
addu $t0,$a2,$t4 # &arr2[index]
lw $a1,0($t0) # arr2[index]
jal add1
lw $a3,36($sp) # retrieve args from home loc.
lw $a2,32($sp)
lw $a1,28($sp)
lw $a0,24($sp)
sll $t4,$s0,2
addu $t0,$a0,$t4 # & result[index]
sw $v0,0($t0) #
result[index] = $v0
addi $s0,$s0,1 # index++
b .Larrloop
.Larrdone:
li $v0,0
.Larrbad:
lw $ra,20($sp)
lw $s0,16($sp)
addu $sp,$sp,24
jr $ra
The code is absolutely ridiculous in assembler. If the add
instruction was put back into arradd() instead of calling the add1
function (called inlining
the function), what percentage of the instructions would be saved?
Calculate it for an array length of 10 elements. (The instructions
above in bold face
indicate the instructions that would be omitted if an appropriate
add instruction was used instead of a call to a function. A quick
estimate is 30% savings by inlining the function.)
The code for add1.s,
arradd.s and the code with a main program, arradd_all.s is in the
online/mipsIII directory.
strcat2.s
The function strcat2()
in strcat2.s takes two strings
of any length. strcat2()
allocates space for a new string sufficient in size to concatenate
the two strings together using the actual length of the two
strings, then concatenates the strings and returns a pointer to
the new string.
The strcat2() function calls the function int strlen(char *str) to get the length of each string. strlen() is part of util.s, but is copied here as well.
strcat2 is a bit complicated because it will accept strings entered by MARS syscalls as well as the functions in util.s. Since MARS' syscalls have a habit of leaving newlines on the end of strings (which the util.s functions clean up), strcat2 must search for either the newline or nul.
Let's write strcat in C first:
Let's uglify it next:
This is going to be a lot of assembler code. To avoid confusion,
the code below has limited C code inserted, and it is only from
the uglified version.
This code above does not include the main program, which should request two strings from the user and place them in static storage (with a max length of 100). It then calls strcat2 with the strings and prints the result. Using functions from util.s, the main program is fairly simple. It is shown below:
The writing of the main program is left up to you.
The strcat2 function is in strcat2.c, strcat2-1.c and strcat2.s in the online/mipsIV directory. The file strcat2-all.s includes strcat2.s and the main program. It, of course, uses functions from util.s
You could more easily write strcat2.s using strcpy()
Prev | This page was made entirely
with free software on linux: Kompozer and Openoffice.org |
Next |