Professional Documents
Culture Documents
MehmetEmreKantaş CS224-001 PRELIM Lab3
MehmetEmreKantaş CS224-001 PRELIM Lab3
#mergeSortedLists.asm
.text
main:
enterFirst:
li $v0, 5
syscall
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:
continueFirst:
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:
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:
secondListEmpty:
continueSecond:
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:
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
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)
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
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
lw $s2, 4($s0)
j firstLessThanSecond #jumping to the firstLessThanSecond label to store
the data in register s2 to heap memory
bothFilled:
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:
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
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
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
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
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 $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)
move $s4, $v0 #storing the first input in the data register s4
addNode:
allDone:
move $v0, $s3 #storing the address of the output list to the
return register v0
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)
printNextNode:
beq $s0, $zero, printedAll #control statement
la $a0, nodeNumberLabel
li $v0, 4
syscall
la $a0, addressOfCurrentNodeLabel
li $v0, 4
syscall
move $a0, $s0
li $v0, 34
syscall
la $a0, addressOfNextNodeLabel
li $v0, 4
syscall
move $a0, $s1
li $v0, 34
syscall
lastNode:
la $a0, dataValueOfCurrentNode
li $v0, 4
syscall
printedAll:
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"