Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 10

##############################PRELIMINARY PART1##############################

#mergeSortedLists.asm
.text
main:

#printing welcome message


la $a0, welcome
li $v0, 4
syscall

enterFirst:

#prompting the user to enter the first lists size


la $a0, enterFirstSize
li $v0, 4
syscall

li $v0, 5
syscall

move $s0, $v0 #saving the first list size to register s0

blt $s0, $0, invalidSizeFirst #if the input is less than zero, take the
input again and print the invalidSizeMessage
j correctSizeFirst

invalidSizeFirst:

la $a0, invalidSizeMessage
li $v0, 4
syscall
j enterFirst

correctSizeFirst:

beq $s0, 0, firstListEmpty #if the first list is empty, just print
firstListIsEmpty message and
j continueFirst #take the second lists size

firstListEmpty:

#print firstListIsEmpty message


la $a0, firstListIsEmpty
li $v0, 4
syscall
j enterSecond

continueFirst:

#prompting the user to enter the elements of the first list if it is


not empty
la $a0, enterFirstList
li $v0, 4
syscall

move $a0, $s0 #register a0 holds the size of the first array as an
argument
jal inputList #filling the list in the inputList subprogram
move $s1, $v0 #register v0 holds the address of the list head of
the first list
#now, register s1 holds it

move $a0, $s1 #register a0 holds the address of the list head of
the first list as an argument
jal printList #printing the first list in the printList subprogram

enterSecond:

#prompting the user to enter the second lists size


la $a0, enterSecondSize
li $v0, 4
syscall

li $v0, 5
syscall

move $s2, $v0 #register s2 now holds the size of the second list

blt $s2, $0, invalidSizeSecond #if the input is less than zero,
take the input again and print the invalidSizeMessage
j correctSizeSecond

invalidSizeSecond:

la $a0, invalidSizeMessage
li $v0, 4
syscall
j enterSecond

correctSizeSecond:

beq $s2, 0, secondListEmpty #if second list is empty, print the


secondListIsEmpty message and continue
j continueSecond #if size is not zero, take list elements

secondListEmpty:

#printing the secondListIsEmpty message


la $a0, secondListIsEmpty
li $v0, 4
syscall
j listsEntered

continueSecond:

#prompting the user to enter the second lists elements


la $a0, enterSecondList
li $v0, 4
syscall

move $a0, $s2 #register a0 now holds the size of the second list as
an argument
jal inputList #filling the list in the inputList subprogram
move $s3, $v0 #register v0 holds the address of the list head of
the second list
#now, register s3 holds it

move $a0, $s3 #register a0 now holds the address of the list head
of the second list as an argument
jal printList #jumping to the printList subprogram to print the
second list

listsEntered:

move $a0, $s1 #register a0 holds the address of the list head of
the first list
move $a1, $s3 #register a1 holds the address of the list head of
the second list
move $a2, $s0 #register a2 holds the size of the first list
move $a3, $s2 #register a3 holds the size of the second list
jal mergeSortedLists #all "a" registers holds arguments for the
mergeSortedLists subprogram, jumping

beq $t3, 1, useAgain #if both lists are empty, register t3 will be set to
1
#if register t3 holds 1, don't print the merged list and
jump to useAgain label
move $a0, $v0 #if both lists are not empty at the same time, print
the merged list
jal printList #jumping to the subprogram printList to print the
merged list

useAgain:

la $a0, again #prompting the user to select 1 if they want to use


the program again
li $v0, 4 #or 0 to quit
syscall

li $v0, 12 #taking this input as a char to catch invalid inputs


syscall

beq $v0, 48, quit #if the input is zero (48 in ASCII), terminate
the program
beq $v0, 49, enterFirst #if the input is one (49 in ASCII), go to
the enterFirst label to run the program again

la $a0, invalidInput #if the input is neither one nor zero,


print invalidInput message
li $v0, 4 #and take a new input
syscall
j useAgain

mergeSortedLists:

addi $sp, $sp, -36 #save the original values of the registers that
will be used in this subprogram
sw $s0, 32($sp)
sw $s1, 28($sp)
sw $s2, 24($sp)
sw $s3, 20($sp)
sw $s4, 16($sp)
sw $s5, 12($sp)
sw $s6, 8($sp)
sw $s7, 4($sp)
sw $ra, 0($sp)
move $s0, $a0 #head of first list
move $s1, $a1 #head of the second list
move $s6, $a2 #size of the first list
move $s7, $a3 #size of the second list

li $a0, 8
li $v0, 9
syscall #allocating heap memory

move $s4, $v0 #address on the merged list (will be used like an
index value)
move $s5, $v0 #head of the merged list (will be the address of the
output list)

seq $t0, $s6, $0 #register t0 holds 1 if the first list is empty


seq $t1, $s7, $0 #register t1 holds 1 if the second list is empty
and $t3, $t0, $t1 #register t3 holds 1 if both lists are empty

beq $t3, 1, mergeDone #if both lists are empty, skip this part and print
the bothEmpty message

beq $t0, 1, calculateSecond #if the first list is empty, take the second
lists element, store it in the allocated heap memory
beq $t1, 1, calculateFirst #if the second list is empty, take the first
lists element, store it in the allocated heap memory

j bothFilled #if none of the lists are empty, continue

calculateSecond: #takes the data at the first node of the second list

lw $s3, 4($s1)
j secondLessThanFirst #jumping to the secondLessThanFirst label to store
the data in register s3 to heap memory

calculateFirst: #takes data at the first node of the first list

lw $s2, 4($s0)
j firstLessThanSecond #jumping to the firstLessThanSecond label to store
the data in register s2 to heap memory

bothFilled:

#taking data in the current nodes of the lists


lw $s2, 4($s0)
lw $s3, 4($s1)

beq $s2, $s3, same #if the data are equal, jump to the "same"
label
blt $s2, $s3, firstLTSecond #if the first lists value is less than the
second lists value, jump to the firstLTSecond label

sw $s3, 4($s4) #if second lists value is less than the first lists
value, program reaches that part of the code
addi $s1, $s1, 8 #adjusting the address to the next node
addi $s7, $s7, -1 #decrementing the size value to keep track of the loop
j loopMerge #jump to the loopMerge label to not to execute the code
segment which is not needed if the program execution
#reached to this point
same: #if the data are the same, store the data to the current heap
memory, get the next nodes of both lists and
#decrement their size values to keep track of the loop

sw $s2, 4($s4)
addi $s0, $s0, 8
addi $s1, $s1, 8
addi $s6, $s6, -1
addi $s7, $s7, -1
j loopMerge #jump to the loopMerge label to not to execute the code
segment which is not needed if the program execution
#reached to this point

firstLTSecond: #if the first data is less than the second data,
store the first data to the heap memory
#get the address of the next node of the first list and
decrement the size value to keep track of the loop

sw $s2, 4($s4)
addi $s0, $s0, 8
addi $s6, $s6, -1

loopMerge:

#control statement of the loop


seq $t0, $s6, $0
seq $t1, $s7, $0
and $t2, $t0, $t1
beq $t2, 1, mergeDone

#allocating heap memory


li $a0, 8
li $v0, 9
syscall

#saving the allocated heap memory address to register s4 to store data


in it
sw $v0, 0($s4)
move $s4, $v0

beq $t0, 1, firstEmpty


beq $t1, 1, secondEmpty
j cont

firstEmpty: #if the first list is empty, get the second data and jump
to the secondLessThanFirst label

lw $s3, 4($s1)
j secondLessThanFirst

secondEmpty: #if the second list is empty, get the first data and
jump to the firstLessThanSecond label

lw $s2, 4($s0)
j firstLessThanSecond

cont:
lw $s2, 4($s0) #data in first
lw $s3, 4($s1) #data in second

beq $s2, $s3, sameData #jump to sameData label if the data


are equal
blt $s2, $s3, firstLessThanSecond #jump to firstLessThanSecond label
if the first data is less than the second data

secondLessThanFirst: #store the second data in the heap


memory, get the next node of the second list,
#decrement the size of the list to keep track
of the loop
sw $s3, 4($s4)
addi $s1, $s1, 8
addi $s7, $s7, -1
j loopMerge

sameData: #if the data are the same, store the data to the current
heap memory, get the next nodes of both lists and
#decrement their size values to keep track of the loop

sw $s2, 4($s4)
addi $s0, $s0, 8
addi $s1, $s1, 8
addi $s6, $s6, -1
addi $s7, $s7, -1
j loopMerge

firstLessThanSecond: #if the first data is less than the second


data, store the first data to the heap memory
#get the address of the next node of the first list
and decrement the size value to keep track of the loop

sw $s2, 4($s4)
addi $s0, $s0, 8
addi $s6, $s6, -1
j loopMerge

mergeDone:

beq $t3, 1, bothListsAreEmpty #if both lists are empty (decided by the
register t3) jump to the bothListsAreEmpty label
j bothNotEmpty #if not both lists are empty, jump to
bothNotEmpty label

bothListsAreEmpty: #if both lists are empty, print the bothEmpty


message and terminate the execution of the subprogram

la $a0, bothEmpty
li $v0, 4
syscall
j return

bothNotEmpty: #if not both lists are empty, store the address of
the merged list to the return register v0

move $v0, $s5

return: #go to the main


lw $ra, 0($sp) #deallocate the stack memory
lw $s7, 4($sp)
lw $s6, 8($sp)
lw $s5, 12($sp)
lw $s4, 16($sp)
lw $s3, 20($sp)
lw $s2, 24($sp)
lw $s1, 28($sp)
lw $s0, 32($sp)
addi $sp, $sp, 36
jr $ra

inputList:

addi $sp, $sp, -24 #save the original values of the registers that will
be used in this subprogram
sw $s0, 20($sp)
sw $s1, 16($sp)
sw $s2, 12($sp)
sw $s3, 8($sp)
sw $s4, 4($sp)
sw $ra, 0($sp)

move $s0, $a0 #store the size of the lists size


li $s1, 1

li $a0, 8 #allocate heap memory


li $v0, 9
syscall

move $s2, $v0 #address on the list (will be used like an index
value)
move $s3, $v0 #head of the list (will be the address of the output
list)

li $v0, 5 #taking the first input


syscall

move $s4, $v0 #storing the first input in the data register s4

sw $s4, 4($s2) #storing the data in the register s4 to the current


heap memory

addNode:

beq $s1, $s0, allDone #control statement of the loop, if all


nodes added, go to the allDone label
addi $s1, $s1, 1 #increment the node counter by one to keep
track of the loop

li $a0, 8 #allocating heap memory


li $v0, 9
syscall

sw $v0, 0($s2) #connecting the current node to the next


node
move $s2, $v0 #now, getting to the next node

li $v0, 5 #taking the element as an input


syscall

move $s4, $v0 #storing the input data to the data


register s4
sw $s4, 4($s2) #storing the data to the heap memory
j addNode #getting to the control statement of the loop

allDone:

move $v0, $s3 #storing the address of the output list to the
return register v0

lw $ra, 0($sp) #deallocating the stack memory


lw $s4, 4($sp)
lw $s3, 8($sp)
lw $s2, 12($sp)
lw $s1, 16($sp)
lw $s0, 20($sp)
addi $sp, $sp, 24

jr $ra

printList:

addi $sp, $sp, -20 #save the original values of the registers that
will be used in this subprogram
sw $s0, 16($sp)
sw $s1, 12($sp)
sw $s2, 8($sp)
sw $s3, 4($sp)
sw $ra, 0($sp)

move $s0, $a0 #store the address of the list to register s0


li $s3, 0 #node counter

printNextNode:
beq $s0, $zero, printedAll #control statement

lw $s1, 0($s0) #storing the next nodes address


lw $s2, 4($s0) #data of the current node
addi $s3, $s3, 1 #increment the node counter to print correctly

#printing the list in the correct order


la $a0, line
li $v0, 4
syscall

la $a0, nodeNumberLabel
li $v0, 4
syscall

move $a0, $s3


li $v0, 1
syscall

la $a0, addressOfCurrentNodeLabel
li $v0, 4
syscall
move $a0, $s0
li $v0, 34
syscall

beq $s1, 0, lastNode

la $a0, addressOfNextNodeLabel
li $v0, 4
syscall
move $a0, $s1
li $v0, 34
syscall

lastNode:

la $a0, dataValueOfCurrentNode
li $v0, 4
syscall

move $a0, $s2


li $v0, 1
syscall

move $s0, $s1


j printNextNode

printedAll:

lw $ra, 0($sp) #deallocating the stack memory


lw $s3, 4($sp)
lw $s2, 8($sp)
lw $s1, 12($sp)
lw $s0, 16($sp)
addi $sp, $sp, 20
jr $ra

quit:
#terminating the execution of the code after saying goodbye to the user
la $a0, goodbye
li $v0, 4
syscall

li $v0, 10
syscall

###################################################################################
##################################################
.data
line:
.asciiz "\n--------------------------------------"

nodeNumberLabel:
.asciiz "\nNode No.: "

addressOfCurrentNodeLabel:
.asciiz "\nAddress of Current Node: "
addressOfNextNodeLabel:
.asciiz "\nAddress of Next Node: "

dataValueOfCurrentNode:
.asciiz "\nData Value of Current Node: "

welcome:
.asciiz "\nWelcome to the linked list merge!\n"

enterFirstSize:
.asciiz "\nEnter the first list size: "

enterFirstList:
.asciiz "Enter the first list(x if finished): "

enterSecondSize:
.asciiz "\nEnter the second list size: "

enterSecondList:
.asciiz "Enter the second list(x if finished): "

again:
.asciiz "\nEnter 0 to quit and 1 to use the program again: "

goodbye:
.asciiz "\nGoodBye!"

invalidInput:
.asciiz "\nInvalid input! Enter again!"

firstListIsEmpty:
.asciiz "First list is empty!"

secondListIsEmpty:
.asciiz "Second list is empty!"

bothEmpty:
.asciiz "\nBoth lists are empty. Nothing to merge!"

invalidSizeMessage:
.asciiz "\nYou cannot enter a negative list size!\n"

You might also like