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