This commit is contained in:
unlockable
2024-05-03 23:53:44 +08:00
parent 64771f7a0c
commit 01c334e7f7

View File

@@ -0,0 +1,252 @@
.data
compare_count: .word 0
num_N: .word 0
input_file_name: .asciiz "a.in"
.align 2
output_file_name: .asciiz "a.out"
.align 2
space_string: .asciiz " "
.align 2
newline_string: .asciiz "\r\n"
.align 2
num_buff: .space 4096
.align 2
.text
main:
la $a0, input_file_name
li $a1, 0
li $a2, 0
li $v0, 13
syscall
move $a0, $v0 # start to read in N
la $a1, num_N
li $a2, 4
li $v0, 14
syscall
la $t0, num_N # read N * 4 bytes into num_buff
lw $a2, 0($t0) # read in num_N
sll $a2, $a2, 2 # n * 4 is the bytes to read
la $a1, num_buff
li $v0, 14
syscall # read in file
li $v0, 16
syscall # close file
la $t0, num_N
lw $s0, 0($t0) # s0 = N
li $a0, 8
li $v0, 9
syscall
move $s2, $v0 # headptr in s2
move $s3, $s2 # curnodeptr = headptr
li $s1, 0 # s1 = index
la $t0, num_buff
create_linked_list:
bge $s1, $s0, done_create_linked_list
li $v0, 9
syscall # new int[2]
sw $v0, 4($s3) # curnodeptr[1] = new int[2]
move $s3, $v0 # curnodeptr = curnodeptr[1]
sll $t1, $s1, 2 # curnodeptr[0] = num_buffer[index]
add $t1, $t0, $t1
lw $t1, 0($t1)
sw $t1, 0($s3)
sw $zero, 4($s3) # curnodeptr[1] = NULL
addi $s1, $s1, 1
j create_linked_list
done_create_linked_list:
# lw $a0, 4($s2) #a0 = headnodeptr[1]
# jal print_num
lw $a0, 4($s2) #a0 = headnodeptr[1]
jal merge_sort
sw $v0, 4($s2)
move $s1, $s2 # curptr = headptr
# lw $a0, 4($s2) #a0 = headnodeptr[1]
# jal print_num
la $a0, output_file_name
li $a1, 1
li $a2, 0
li $v0, 13
syscall
move $a0, $v0
la $a1, compare_count
li $a2, 4
li $v0, 15
syscall
write_linked_list:
lw $s1, 4($s1) # curptr = curptr[1]
beq $s1, $zero, done_write_linked_list
move $a1, $s1
li $v0, 15
syscall
j write_linked_list
done_write_linked_list:
li $v0, 16
syscall
li $v0, 17
syscall # exit
merge_sort: # a0: headnodeptr
subi $sp, $sp, 20
sw $s0, 16($sp)
sw $s1, 12($sp)
sw $s2, 8($sp)
sw $s3, 4($sp)
sw $ra, 0($sp)
lw $t0, 4($a0) # t0 = headnodeptr[1]
bne $t0, $zero, valid_head # if headnodeptr[1] != NULL, valid head
move $v0, $a0 # no valid head
j done_merge_sort
valid_head:
move $s1, $a0 # stride 1 pointer
move $s2, $a0 # stride 2 pointer
find_mid:
lw $s2, 4($s2) # s2 = s2[1]
beq $s2, $zero, done_find_mid # s2 == NULL, break
lw $s2, 4($s2) # s2 = s2[1]
beq $s2, $zero, done_find_mid # s2 == NULL, break
lw $s1, 4($s1)
j find_mid
done_find_mid:
lw $s2, 4($s1) # now s2 is the headnodeptr of the right part
sw $zero, 4($s1)
jal merge_sort # no need to set a0 to head, it already is
move $s1, $v0 # save the result of first merge_sort to s1
move $a0, $s2
jal merge_sort # merge_sort for right part
# move $a0, $s1
# jal print_num
# move $a0, $v0
# jal print_num
move $a0, $s1
move $a1, $v0
jal merge_list
done_merge_sort:
lw $s0, 16($sp)
lw $s1, 12($sp)
lw $s2, 8($sp)
lw $s3, 4($sp)
lw $ra, 0($sp)
addi $sp, $sp, 20
jr $ra
merge_list: # a0: l_head, a1: r_head
subi $sp, $sp, 28
sw $s0, 24($sp)
sw $s1, 20($sp)
sw $s2, 16($sp)
sw $s3, 12($sp)
sw $s4, 8($sp)
sw $s5, 4($sp)
sw $ra, 0($sp)
move $s0, $a0 # lheadptr
move $s1, $a1 # s1 = rheadptr
li $a0, 8
li $v0, 9
syscall # create dummy node
sw $s0, 4($v0) # headnodeptr[1] = lheadptr
move $s0, $v0 # p_left = headnodeptr; p_right = rightptr, no change.
move $s7, $v0 # head
do_merge_list: # outer while
find_left_merge_pos:
lw $s2, 4($s0) #p_left[1]
beq $s2, $zero, direct_add_right_part
jal add_compare_count
lw $s2, 0($s2) # (p_left[1])[0]
lw $t0, 0($s1) # p_right[0]
bgt $s2, $t0, no_direct_add_right_part
lw $s0, 4($s0)
j find_left_merge_pos
direct_add_right_part:
sw $s1, 4($s0)
j done_do_merge_list
no_direct_add_right_part:
move $s2, $s1 # p_right_temp
lw $s5, 4($s0)
lw $s5, 0($s5) # (p_left[1])[0]
find_right_merge_pos:
lw $s3, 4($s2) # p_right_temp[1]
beq $s3, $zero, done_find_right_merge_pos
jal add_compare_count
lw $s4, 0($s3) # (p_right_temp[1])[0]
bgt $s4, $s5, done_find_right_merge_pos
move $s2, $s3 # p_right_temp = p_right_temp[1]
j find_right_merge_pos
done_find_right_merge_pos:
move $s4, $s3 # temp_right_pointer_next
lw $t0, 4($s0) # p_left[1]
sw $t0, 4($s2) # p_right_temp[1] = p_left[1]
sw $s1, 4($s0) # p_left[1] = p_right
move $s0, $s2
move $s1, $s4
beq $s1, $zero, done_do_merge_list
j do_merge_list
done_do_merge_list:
lw $v0, 4($s7)
done_merge_list:
lw $s0, 24($sp)
lw $s1, 20($sp)
lw $s2, 16($sp)
lw $s3, 12($sp)
lw $s4, 8($sp)
lw $s5, 4($sp)
lw $ra, 0($sp)
addi $sp, $sp, 28
jr $ra
add_compare_count:
la $t0, compare_count
lw $t1, 0($t0)
addi $t1, $t1, 1
sw $t1, 0($t0)
jr $ra
print_num: #a0: headptr
subi $sp, $sp, 8
sw $t0, 4($sp)
sw $v0, 0($sp)
move $t0, $a0
print_loop:
lw $a0, 0($t0)
li $v0, 1
syscall
la $a0, space_string
li $v0, 4
syscall
lw $t0, 4($t0)
beq $t0, $zero, done_print_num
j print_loop
done_print_num:
la $a0, newline_string
li $v0, 4
syscall
lw $t0, 4($sp)
lw $v0, 0($sp)
addi $sp, $sp, 8
jr $ra