# Shawn Olson
# C SC 252
# Instructor: Patrick Homer
#
# **prog4.s**
#
# Purpose: Create a subroutine convert that takes in an ascii string and takes any
# prepending spaces or tabs out of the phrase, and replaces any capital letters with
# lower case letters. This subroutine also outputs the number of characters read in
# and gives them to the main method.
.data
mainNumPhrases:
.word 3
mainPhrases:
.word mainPhrase1
.word mainPhrase2
.word mainPhrase3
mainPhrase1:
.asciiz "A man, a plan, a canal, Panama!"
mainPhrase2:
.asciiz " CSc252 -- Computer Organization "
mainPhrase3:
.asciiz " Three Tabs To StarT This Line "
mainOriginalStr:
.asciiz "The original string:\n"
mainTotalStr:
.asciiz "Total character count: "
mainNewline:
.asciiz "\n"
.text
main:
# Function prologue -- even main has one
subu $sp, $sp, 24 # allocate stack space
sw $fp, 0($sp) # save frame pointer of caller
sw $ra, 4($sp) # save return address
addiu $fp, $sp, 24 # setup frame pointer of main
la $t0, mainNumPhrases
lw $s0, 0($t0) # $s0 = mainNumPhrases
# skip everything if there are no phrases
beq $s0, $zero, mainDone
# for i = 0 to mainNumPhrases - 1
# print phrase
# call convert
addi $s1, $zero, 0 # $s1 = i
la $s2, mainPhrases # $s2 = mainPhrases[i]
lw $s3, 0($s2) # $s3 = address of current phrase
addi $s4, $zero, 0 # $s4 = character count = 0
mainLoopBegin:
# if i < mainNumPhrases
slt $t3, $s1, $s0 # $t3 = i < mainNumPhrases
beq $t3, $zero, mainLoopEnd
# print the current phrase
la $a0, mainOriginalStr
li $v0, 4
syscall
addi $a0, $s3, 0 # $a0 = address of current phrase
li $v0, 4
syscall
la $a0, mainNewline
la $v0, 4
syscall
# Startup Sequence:
addi $a0, $s3, 0 # $a0 = address of current phrase
jal convert
# Clean up: get count of characters
add $s4, $s4, $v0 # $s4 += count
# print blank line
la $a0, mainNewline
li $v0, 4
syscall
addi $s1, $s1, 1 # i++
addi $s2, $s2, 4 # $s2 = address of next phrase
lw $s3, 0($s2) # $s3 = next phrase
j mainLoopBegin
mainLoopEnd:
# print the total character count
la $a0, mainTotalStr
li $v0, 4
syscall
addi $a0, $s4, 0
li $v0, 1
syscall
la $a0, mainNewline
li $v0, 4
syscall
mainDone:# Epilogue for main -- restore stack & frame pointers
lw $ra, 4($sp) # get return address from stack
lw $fp, 0($sp) # restore frame pointer of caller
addiu $sp, $sp, 24 # restore stack pointer of caller
jr $ra # return to caller
.data
printLineNewline:
.asciiz "\n"
printLineModifiedStr:
.asciiz "The modified string:\n"
.text
printLine:
# Function prologue
subu $sp, $sp, 24 # allocate stack space
sw $fp, 0($sp) # save frame pointer of caller
sw $ra, 4($sp) # save return address
sw $a0, 8($sp) # save the address of the string
addiu $fp, $sp, 24 # setup frame pointer for printLine
la $a0, printLineModifiedStr
li $v0, 4
syscall
lw $a0, 8($sp)
li $v0, 4
syscall
la $a0, printLineNewline
li $v0, 4
syscall
printLineDone:
# Epilogue for printLine -- restore stack & frame pointers
lw $a0, 8($sp) # restore the address of string
lw $ra, 4($sp) # get return address from stack
lw $fp, 0($sp) # restore frame pointer of caller
addiu $sp, $sp, 24 # restore stack pointer of caller
jr $ra # return to caller
# Your code goes below this line
.data
TestText: .asciiz "stuff"
.text
convert:
subu $sp, $sp, 24 # allocate stack space
sw $fp, 0($sp) # save frame pointer of caller
sw $ra, 4($sp) # save return address
sw $a0, 8($sp) # save the address of the string
addiu $fp, $sp, 24 # setup frame pointer for printLine
ConvertCheckWhiteSpaceStart:
lb $t7, 0($a0)
beq $t7, 9, ConvertWhiteSpace
beq $t7, 32, ConvertWhiteSpace
# not white space, start with the actual program
j ConvertStartForReal
ConvertWhiteSpace:
add $a0, $a0, 1
j ConvertCheckWhiteSpaceStart
ConvertStartForReal:
# beginning of string -- store $a0's address into $t7 and use $t6 to traverse
add $t7, $a0, $zero
# add 0x00000040 and 0x0000005a to $t4 and $t2, respectively
addi $t4, $zero, 65
addi $t2, $zero, 90
# use $t0 as a counter
add $t0, $zero, $zero
ConvertCheckForCapitalsStart:
lb $t6, 0($t7)
# break out of loop if $t6 is 0
beq $t6, $zero, ConvertCheckLoopFinished
# increment $t0
add $t0, $t0, 1
# check to see if the byte in $t6 is less than $t4 (capital A)
slt $t5, $t6, $t4
bne $t5, $zero, ConvertGoToEnd
# greater than capital A, check if it is less than $t2 (capital Z +1)
slt $t5, $t2, $t6
bne $t5, $zero, ConvertGoToEnd
# if it gets here, then it was a capital, therefore, add 32 to $t6
add $t6, $t6, 32
sb $t6, 0($t7)
ConvertGoToEnd:
# store the byte at $t6 into $t7
sb $t6, 0($t7)
# add 1 to $t7 to move on
add $t7, $t7, 1
j ConvertCheckForCapitalsStart
ConvertCheckLoopFinished:
add $t7, $a0, $zero
add $a0, $t0, $zero
li $v0, 1
syscall
add $a0, $t7, $zero
# loop is finished, therefore, send the print function $a0
add $v0, $t0, $zero
jal printLine
lw $a0, 8($sp) # restore the address of string
lw $ra, 4($sp) # get return address from stack
lw $fp, 0($sp) # restore frame pointer of caller
addiu $sp, $sp, 24 # restore stack pointer of caller
jr $ra # return to caller