-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheapSort.asm
More file actions
237 lines (168 loc) · 4.85 KB
/
heapSort.asm
File metadata and controls
237 lines (168 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
.data
# Actual information
arr: .word 2, 5, 100, 33, 92, 6, 7, 11, 32, 69
arr_len: .word 10
# Formatting
arr_original_prompt: .asciiz "Original array: \n"
arr_sorted_prompt: .asciiz "Sorted array: \n"
spacer: .ascii ", "
newline: .ascii "\n"
.text
.globl main
main:
addi $sp, $sp, -4
lw $t0, arr_len
sw $t0, 0($sp) # store arr_len because it is reduced by heapsort_extraction
li $v0, 4
la $a0, arr_original_prompt # print unsorted prompt
syscall
li $a1, 0 # init index to 0
jal print_arr # print base arr
sll $zero, $zero, 0
lw $a0, arr_len
srl $a0, $a0, 1
addi $a0, $a0, -1 # index of last non-leaf node
jal heapsort
sll $zero, $zero, 0
lw $a0, arr_len
addi $a0, $a0, -1 # index of last value
jal heapsort_extraction
sll $zero, $zero, 0
li $v0, 4
la $a0, arr_sorted_prompt # print sorted prompt
syscall
lw $t0, 0($sp)
la $t1, arr_len
sw $t0, 0($t1) # restore original value of arr_len
addi $sp, $sp, 4 # restore memory
li $a1, 0 # init index to 0
jal print_arr # print sorted array
sll $zero, $zero, 0
li $v0, 10 # exit
syscall
# --------------------------------
# a0 = index of last non-leaf node
# --------------------------------
heapsort:
addi $sp, $sp, -8
sw $ra, 0($sp) # store return for jal heapify
sw $a0, 4($sp) # store a0 for jal heapify
jal heapify
sll $zero, $zero, 0
lw $ra, 0($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8
addi $a0, $a0, -1 # move the index to the previous non-leaf node
bgez $a0, heapsort # if index is in array bounds, repeat
sll $zero, $zero, 0
jr $ra
# ------------------------------------------------------
# a0 contains the index of the last value in reduced arr
# ------------------------------------------------------
heapsort_extraction:
addi $sp, $sp, -8
sw $ra, 0($sp) # store return for jal heapify
sw $a0, 4($sp) # store a0 for jal heapify
la $t0, arr
la $t1, arr_len
sll $t2, $a0, 2
add $t2, $t2, $t0 # location of last val in arr
# swap arr[0] and arr[last]
lw $t3, 0($t0)
lw $t4, 0($t2)
sw $t3, 0($t2)
sw $t4, 0($t0)
lw $t5, 0($t1)
addi $t5, $t5, -1
sw $t5, 0($t1) # arr_length--
add $a0, $zero, $zero
jal heapify # heapify at new root
sll $zero, $zero, 0
lw $ra, 0($sp) # reobtain return address
lw $a0, 4($sp) # reobtain final index
addi $sp, $sp, 8
addi $a0, $a0, -1 # new final index
bgtz $a0, heapsort_extraction # arr_len > 0 repeat
sll $zero, $zero, 0
jr $ra
# -----------------------------
# a0 contains parent node index
# -----------------------------
heapify:
addi $sp, $sp, -8
sw $ra, 0($sp) # store return for recursive calls
sw $a0, 4($sp) # store i for recursive calls & largest checks
sll $s0, $a0, 1
addi $s0, $s0, 1 # s0 contains index of i->left
sll $s1, $a0, 1
addi $s1, $s1, 2 # s1 contains index of i->right
la $t0, arr # store &arr[]
sll $s2, $a0, 2
add $s2, $s2, $t0
lw $s2, 0($s2) # s2 contains arr[largest]
sll $s3, $s0, 2
add $s3, $s3, $t0
lw $s3, 0($s3) # s3 contains arr[i->left]
sll $s4, $s1, 2
add $s4, $s4, $t0
lw $s4, 0($s4) # s4 contains arr[i->right]
left_largest_checks:
lw $t0, arr_len # obtain arr_len
la $t1, arr # obtain arr address
bge $s0, $t0, right_largest_checks # skip swap if left >= n
sll $zero, $zero, 0
bge $s2, $s3, right_largest_checks # skip swap if arr[largest] >= arr[i->left]
sll $zero, $zero, 0
move $a0, $s0 # largest = left
sll $s2, $a0, 2
add $s2, $s2, $t1
lw $s2, 0($s2) # set s2 to the new largest
right_largest_checks:
lw $t0, arr_len # obtain arr_len
bge $s1, $t0, root_largest_checks # skip swap if right >= n
sll $zero, $zero, 0
bge $s2, $s4, root_largest_checks # skip swap if arr[largest] >= arr[i->right]
sll $zero, $zero, 0
move $a0, $s1 # largest = right
root_largest_checks:
la $t0, arr # store &arr[]
lw $t1, 4($sp) # reobtain original largest index
beq $a0, $t1, heapify_return # skip swap if root != largest
sll $t2, $a0, 2
add $t2, $t2, $t0 # arr[largest]
sll $t3, $t1, 2
add $t3, $t3, $t0 # arr[i]
# swap arr[largest] and arr[i]
lw $t4, 0($t2)
lw $t5, 0($t3)
sw $t4, 0($t3)
sw $t5, 0($t2)
add $t0, $zero, $zero # reset t0 because jal
add $t1, $zero, $zero # reset t1 because jal
jal heapify
sll $zero, $zero, 0
heapify_return:
lw $ra, 0($sp) # restore return for... returning
lw $a0, 4($sp) # restore i for heapsort iteration
addi $sp, $sp, 8
jr $ra
# --------------------
# a1 contains i
# a0 free for syscalls
# --------------------
print_arr:
la $t0, arr # arr address
la $t1, arr_len # arr_len address
sll $t2, $a1, 2
add $t0, $t0, $t2 # adjust index for word size
lw $t0, 0($t0) # obtain arr[i]
lw $t1, 0($t1) # obtain arr_len
li $v0, 1
move $a0, $t0
syscall # print arr[i]
li $v0, 4
la $a0, spacer
syscall # format next print
addi $a1, $a1, 1 # i++
blt $a1, $t1, print_arr # call if i < arr_len
jr $ra # return