2.3
This commit is contained in:
252
1/homework/exp2/merge_sort.asm
Normal file
252
1/homework/exp2/merge_sort.asm
Normal 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
|
||||
Reference in New Issue
Block a user