320 lines
12 KiB
NASM
320 lines
12 KiB
NASM
.text
|
|
#initialize $sp
|
|
lui $sp, 0x4000
|
|
addi $sp, $sp, 0x7fc
|
|
|
|
# load digit to mem
|
|
lui $s0, 0x4000
|
|
addi $s0, $s0, 0x20
|
|
#0
|
|
addi $s1, $zero, 0x3f
|
|
sw $s1, 0($s0)
|
|
#1
|
|
addi $s1, $zero, 0x6
|
|
sw $s1, 4($s0)
|
|
#2
|
|
addi $s1, $zero, 0x5b
|
|
sw $s1, 8($s0)
|
|
#3
|
|
addi $s1, $zero, 0x4f
|
|
sw $s1, 12($s0)
|
|
#4
|
|
addi $s1, $zero, 0x66
|
|
sw $s1, 16($s0)
|
|
#5
|
|
addi $s1, $zero, 0x6d
|
|
sw $s1, 20($s0)
|
|
#6
|
|
addi $s1, $zero, 0x7d
|
|
sw $s1, 24($s0)
|
|
#7
|
|
addi $s1, $zero, 0x7
|
|
sw $s1, 28($s0)
|
|
#8
|
|
addi $s1, $zero, 0x7f
|
|
sw $s1, 32($s0)
|
|
#9
|
|
addi $s1, $zero, 0x6f
|
|
sw $s1, 36($s0)
|
|
#A
|
|
addi $s1, $zero, 0x77
|
|
sw $s1, 40($s0)
|
|
#B
|
|
addi $s1, $zero, 0x7c
|
|
sw $s1, 44($s0)
|
|
#C
|
|
addi $s1, $zero, 0x58
|
|
sw $s1, 48($s0)
|
|
#D
|
|
addi $s1, $zero, 0x5e
|
|
sw $s1, 52($s0)
|
|
#E
|
|
addi $s1, $zero, 0x79
|
|
sw $s1, 56($s0)
|
|
#F
|
|
addi $s1, $zero, 0x71
|
|
sw $s1, 60($s0)
|
|
|
|
main:
|
|
jal disp_num_in_mem
|
|
|
|
lui $t0, 0x4000
|
|
lw $a0, 0x60($t0)
|
|
jal insertion_sort
|
|
end:
|
|
jal disp_num_in_mem
|
|
j end
|
|
|
|
disp_num_in_mem:
|
|
addi $sp, $sp, -20
|
|
sw $ra, 4($sp)
|
|
sw $s0, 8($sp)
|
|
sw $s1, 12($sp)
|
|
sw $s2, 16($sp)
|
|
sw $s3, 20($sp)
|
|
|
|
lui $s0, 0x4000
|
|
# s1 = 0x40000010
|
|
addi $s1, $s0, 0x10
|
|
# s0 = 0x40000060
|
|
addi $s0, $s0, 0x60
|
|
addi $s2, $zero, 0
|
|
# addi $s3, $zero, 20
|
|
lw $s3, 0($s0) # s3 is the total count
|
|
addi $s0, $s0, 4
|
|
display_single_number:
|
|
sll $t0, $s2, 2
|
|
add $t0, $s0, $t0
|
|
lw $a0, 0($t0)
|
|
addi $a1, $s1, 0
|
|
jal display_number
|
|
|
|
addi $s2, $s2, 1
|
|
sub $t0, $s3, $s2
|
|
bgtz $t0, display_single_number
|
|
|
|
|
|
jal display_empty
|
|
|
|
lw $ra, 4($sp)
|
|
lw $s0, 8($sp)
|
|
lw $s1, 12($sp)
|
|
lw $s2, 16($sp)
|
|
lw $s3, 20($sp)
|
|
addi $sp, $sp, 20
|
|
jr $ra
|
|
|
|
# ------------------------------------------------------
|
|
|
|
# a0 is the number to be displayed, a1 is the bcd control addr
|
|
display_number:
|
|
addi $sp, $sp, -32
|
|
sw $ra, 4($sp)
|
|
sw $s0, 8($sp)
|
|
sw $s1, 12($sp)
|
|
sw $s2, 16($sp)
|
|
sw $s3, 20($sp)
|
|
sw $s4, 24($sp)
|
|
sw $s5, 28($sp)
|
|
sw $s6, 32($sp)
|
|
|
|
# s0 is the number to be displayed
|
|
addi $s0, $a0, 0
|
|
|
|
# s1 is the bcd_control addr
|
|
addi $s1, $a1, 0
|
|
|
|
# s2 is the base addr for display digit
|
|
lui $s2, 0x4000
|
|
addi $s2, $s2, 0x20
|
|
|
|
# s3 is the counter for a complete scan of 4 digit
|
|
# addi $s3, $zero, 0x17c4
|
|
addi $s3, $zero, 0xbe2
|
|
all_digit_scan_loop:
|
|
# s4 is the num being shifted gradually
|
|
addi $s4, $s0, 0
|
|
# s6 is the enable digit
|
|
addi $s6, $zero, 0x100
|
|
|
|
addi $s5, $zero, 4
|
|
single_digit_loop:
|
|
# get a digit
|
|
andi $t0, $s4, 0xf
|
|
# digit * 4 is the memory shift
|
|
sll $t0, $t0, 2
|
|
add $t0, $s2, $t0
|
|
lw $t0, 0($t0)
|
|
or $t0, $t0, $s6
|
|
sw $t0, 0($s1)
|
|
|
|
srl $s4, $s4, 4
|
|
sll $s6, $s6, 1
|
|
|
|
addi $t0, $zero, 0x400
|
|
wait_time_loop:
|
|
addi $t0, $t0, -1
|
|
bgtz $t0, wait_time_loop
|
|
|
|
addi $s5, $s5, -1
|
|
bgtz $s5, single_digit_loop
|
|
# end of single digit loop
|
|
|
|
# ** depends on the clock **
|
|
# four digit, 328.68us.
|
|
# 1s / 328.68us = 3042 = (be2)hex
|
|
|
|
addi $s3, $s3, -1
|
|
bgtz $s3, all_digit_scan_loop
|
|
|
|
lw $ra, 4($sp)
|
|
lw $s0, 8($sp)
|
|
lw $s1, 12($sp)
|
|
lw $s2, 16($sp)
|
|
lw $s3, 20($sp)
|
|
lw $s4, 24($sp)
|
|
lw $s5, 28($sp)
|
|
lw $s6, 32($sp)
|
|
addi $sp, $sp, 32
|
|
jr $ra
|
|
|
|
display_empty:
|
|
lui $t0, 0x4000
|
|
addi $t0, $t0, 0x10
|
|
sw $zero, 0($t0)
|
|
|
|
lui $t0, 0x100
|
|
display_empty_wait_loop:
|
|
addi $t0, $t0, -1
|
|
bgtz $t0, display_empty_wait_loop
|
|
jr $ra
|
|
|
|
# a0 is the total number of numbers needed to be sorted
|
|
insertion_sort:
|
|
addi $sp, $sp, -12
|
|
sw $ra, 4($sp)
|
|
sw $s0, 8($sp)
|
|
sw $s1, 12($sp)
|
|
|
|
# la $t0, num_N
|
|
# lw $s0, 0($t0) # n in s0
|
|
addi $s0, $a0, 0
|
|
|
|
# li $s1, 1 # i in s1
|
|
addi $s1, $zero, 1
|
|
item_loop:
|
|
# bge $s1, $s0, done_item_loop # if i >= n, done loop
|
|
sub $t0, $s0, $s1
|
|
blez $t0, done_item_loop
|
|
|
|
li $a0, 0
|
|
addi $a1, $s1, -1
|
|
move $a2, $s1
|
|
jal binary_search
|
|
|
|
move $a0, $v0
|
|
move $a1, $s1
|
|
jal insert
|
|
|
|
addi $s1, $s1, 1 # i ++
|
|
j item_loop
|
|
done_item_loop:
|
|
|
|
lw $ra, 4($sp)
|
|
lw $s0, 8($sp)
|
|
lw $s1, 12($sp)
|
|
addi $sp, $sp, 12
|
|
jr $ra
|
|
|
|
binary_search: # a0: left, a1: right, a2: i
|
|
addi $sp, $sp, -20
|
|
sw $s0, 4($sp)
|
|
sw $s1, 8($sp)
|
|
sw $s2, 12($sp)
|
|
sw $s3, 16($sp)
|
|
sw $ra, 20($sp)
|
|
|
|
# ble $a0, $a1, in_boundary_binary_search # left <= right, in normal position
|
|
sub $t0, $a0, $a1
|
|
blez $t0, in_boundary_binary_search
|
|
|
|
# move $v0, $a0 # now in boundary condition
|
|
add $v0, $a0, $zero
|
|
|
|
j done_binary_search
|
|
|
|
in_boundary_binary_search:
|
|
move $s0, $a0 # in normal situation
|
|
move $s1, $a1
|
|
move $s2, $a2
|
|
add $s3, $s0, $s1 # s3 = mid = (left + right) >> 1
|
|
srl $s3, $s3, 1
|
|
# jal add_compare_count
|
|
|
|
# la $t0, num_buff
|
|
lui $t0, 0x4000
|
|
addi $t0, $t0, 0x64
|
|
|
|
sll $t1, $s3, 2
|
|
add $t1, $t1, $t0
|
|
lw $t1, 0($t1) # t1 = v[mid]
|
|
sll $t2, $s2, 2
|
|
add $t2, $t2, $t0
|
|
lw $t2, 0($t2) # t2 = v[n]
|
|
# ble $t1, $t2, binary_search_right # v[mid] <= v[n], jump to 'else'
|
|
sub $t0, $t1, $t2
|
|
blez $t0, binary_search_right
|
|
binary_search_left:
|
|
addi $a1, $s3, -1
|
|
jal binary_search
|
|
j done_binary_search
|
|
binary_search_right:
|
|
addi $a0, $s3, 1
|
|
jal binary_search
|
|
done_binary_search:
|
|
lw $s0, 4($sp)
|
|
lw $s1, 8($sp)
|
|
lw $s2, 12($sp)
|
|
lw $s3, 16($sp)
|
|
lw $ra, 20($sp)
|
|
addi $sp, $sp, 20
|
|
jr $ra
|
|
|
|
insert: # $a0: int k, $a1: int n
|
|
addi $sp, $sp, -12
|
|
sw $s0, 4($sp)
|
|
sw $s1, 8($sp)
|
|
sw $ra, 12($sp)
|
|
|
|
# la $s0, num_buff # s0 = &v[0]
|
|
lui $s0, 0x4000
|
|
addi $s0, $s0, 0x64
|
|
|
|
sll $t0, $a1, 2
|
|
add $s2, $s0, $t0
|
|
lw $s2, 0($s2) # s2 = tmp = 'pivot' = v[n]
|
|
|
|
addi $s1, $a1, -1 # s1 = i = n - 1
|
|
|
|
insert_loop:
|
|
# blt $s1, $a0, done_insert_loop # i < k, done loop
|
|
sub $t0, $s1, $a0
|
|
bltz $t0, done_insert_loop
|
|
|
|
sll $t0, $s1, 2
|
|
add $t0, $s0, $t0 # t0 = &v[i]
|
|
lw $t1, 0($t0)
|
|
sw $t1, 4($t0)
|
|
|
|
addi $s1, $s1, -1 # i--
|
|
j insert_loop
|
|
done_insert_loop:
|
|
sll $t0, $a0, 2
|
|
add $t0, $s0, $t0
|
|
sw $s2, 0($t0) # t0 = &v[k]
|
|
|
|
lw $s0, 4($sp)
|
|
lw $s1, 8($sp)
|
|
lw $ra, 12($sp)
|
|
addi $sp, $sp, 12
|
|
jr $ra |