forked from darencard/jekyll-now
-
Notifications
You must be signed in to change notification settings - Fork 0
/
p2_pxs2156.s
303 lines (273 loc) · 13.2 KB
/
p2_pxs2156.s
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/******************************************************************************
* Peter Severynen
Program 2
Search and find min and max in an array loaded with random values.
*
******************************************************************************/
.global main
.func main
main:
BL _seedrand @ seed random number generator with current time
MOV R0, #0 @ initialze index variable
writeloop:
CMP R0, #10 @ check to see if we are done iterating
BEQ writedone @ exit loop if done
LDR R1, =a @ get address of a
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
PUSH {R0} @ backup iterator before procedure call
PUSH {R2} @ backup element address before procedure call
BL _getrand @ get a random number
MOV R1, R0 @ move R0 into R1 for mod evaluation
MOV R2, #1000 @ set a constant value for mod evaluation
PUSH {R1} @ store value to stack
PUSH {R2} @ store value to stack
BL _mod_unsigned @ compute the remainder of R1 / R2
POP {R2} @ restore values from stack
POP {R1} @ restore values from stack
MOV R3, R0 @ copy mod result to R3
POP {R2} @ restore element address
STR R0, [R2] @ write the address of a[i] to a[i]
POP {R0} @ restore iterator
ADD R0, R0, #1 @ increment index
B writeloop @ branch to next loop iteration
writedone:
LDR R1, =a @ get address of a
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
LDR R1, [R2] @ read the array at address
PUSH {R0} @ backup register before printf
PUSH {R1} @ backup register before printf
PUSH {R2} @ backup register before printf
POP {R2} @ restore register
POP {R1} @ restore register
POP {R0} @ restore register
MOV R8, R1 @ copy mod result into R8 for min evaluation
MOV R0, #0 @ initialze index variable
readloop:
CMP R0, #10 @ check to see if we are done iterating
BEQ readdone @ exit loop if done
LDR R1, =a @ get address of a
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
LDR R1, [R2] @ read the array at address
PUSH {R0} @ backup register before printf
PUSH {R1} @ backup register before printf
PUSH {R2} @ backup register before printf
MOV R2, R1 @ move array value to R2 for printf
MOV R1, R0 @ move array index to R1 for printf
BL _printf @ branch to print procedure with return
POP {R2} @ restore register
POP {R1} @ restore register
POP {R0} @ restore register
ADD R0, R0, #1 @ increment index
B readloop @ branch to next loop iteration
readdone:
LDR R1, =a @ get address of a and begin search for minimum element
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
LDR R1, [R2] @ read the array at address
MOV R8, R1 @ put 1st element in R8
minloop:
CMP R0, #10 @ check to see if we are done iterating
BEQ minloopdone @ exit loop if done
LDR R1, =a @ get address of a
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
LDR R1, [R2] @ read the array at address
MOVLT R8, R1 @ If the current array element is less than than R8, move it into R8
ADD R0, R0, #1 @ increment index
B minloop @ branch to next loop iteration
minloopdone:
PUSH {R0} @ backup register before printf
PUSH {R1} @ backup register before printf
PUSH {R2} @ backup register before printf
MOV R2, #0 @ move array value to R2 for printf
BL _printfmin @ branch to print procedure with return
POP {R2} @ restore register
POP {R1} @ restore register
POP {R0} @ restore register
LDR R1, =a @ get address of a and begin search for maximum element
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
LDR R1, [R2] @ read the array at address
MOV R9, R1 @ put 1st element in R9
maxloop:
CMP R0, #10 @ check to see if we are done iterating
BEQ maxloopdone @ exit loop if done
LDR R1, =a @ get address of a
LSL R2, R0, #2 @ multiply index*4 to get array offset
ADD R2, R1, R2 @ R2 now has the element address
LDR R1, [R2] @ read the array at address
MOVGT R9, R1 @ If the current array element is greater than R8, move it into R8
ADD R0, R0, #1 @ increment index
B maxloop @ branch to next loop iteration
maxloopdone:
PUSH {R0} @ backup register before printf
PUSH {R1} @ backup register before printf
PUSH {R2} @ backup register before printf
MOV R2, #0 @ move array value to R2 for printf
BL _printfmax @ branch to print procedure with return
POP {R2} @ restore register
POP {R1} @ restore register
POP {R0} @ restore register
B _exit @ branch to exit procedure with no return
_exit:
MOV R7, #4 @ write syscall, 4
MOV R0, #1 @ output stream to monitor, 1
MOV R2, #21 @ print string length
LDR R1, =exit_str @ string at label exit_str:
SWI 0 @ execute syscall
MOV R7, #1 @ terminate syscall, 1
SWI 0 @ execute syscall
_mod_unsigned:
cmp R2, R1 @ check to see if R1 >= R2
MOVHS R0, R1 @ swap R1 and R2 if R2 > R1
MOVHS R1, R2 @ swap R1 and R2 if R2 > R1
MOVHS R2, R0 @ swap R1 and R2 if R2 > R1
MOV R0, #0 @ initialize return value
B _modloopcheck @ check to see if
_modloop:
ADD R0, R0, #1 @ increment R0
SUB R1, R1, R2 @ subtract R2 from R1
_modloopcheck:
CMP R1, R2 @ check for loop termination
BHS _modloop @ continue loop if R1 >= R2
MOV R0, R1 @ move remainder to R0
MOV PC, LR @ return
_printf:
PUSH {LR} @ store the return address
LDR R0, =printf_str @ R0 contains formatted string address
BL printf @ call printf
POP {PC} @ restore the stack pointer and return
_printfmin:
PUSH {LR} @ store the return address
LDR R0, =printf_str_min @ R0 contains formatted string address
BL printf @ call printf
POP {PC} @ restore the stack pointer and return
_printfmax:
PUSH {LR} @ store the return address
LDR R0, =printf_str_max @ R0 contains formatted string address
BL printf @ call printf
POP {PC} @ restore the stack pointer and return
_seedrand:
PUSH {LR} @ backup return address
MOV R0, #0 @ pass 0 as argument to time call
BL time @ get system time
MOV R1, R0 @ pass sytem time as argument to srand
BL srand @ seed the random number generator
POP {PC} @ return
_getrand:
PUSH {LR} @ backup return address
BL rand @ get a random number
POP {PC} @ return
_reg_dump:
PUSH {LR} @ backup registers
PUSH {R0} @ backup registers
PUSH {R1} @ backup registers
PUSH {R2} @ backup registers
PUSH {R3} @ backup registers
PUSH {R14} @ push registers for printing
PUSH {R13} @ push registers for printing
PUSH {R12} @ push registers for printing
PUSH {R11} @ push registers for printing
PUSH {R10} @ push registers for printing
PUSH {R9} @ push registers for printing
PUSH {R8} @ push registers for printing
PUSH {R7} @ push registers for printing
PUSH {R6} @ push registers for printing
PUSH {R5} @ push registers for printing
PUSH {R4} @ push registers for printing
PUSH {R3} @ push registers for printing
PUSH {R2} @ push registers for printing
PUSH {R1} @ push registers for printing
PUSH {R0} @ push registers for printing
LDR R0,=debug_str @ prepare register print
MOV R1, #0 @ prepare R0 print
POP {R2} @ prepare R0 print
MOV R3, R2 @ prepare R0 print
BL printf @ print R0 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #1 @ prepare R1 print
POP {R2} @ prepare R1 print
MOV R3, R2 @ prepare R1 print
BL printf @ print R1 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #2 @ prepare R2 print
POP {R2} @ prepare R2 print
MOV R3, R2 @ prepare R2 print
BL printf @ print R2 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #3 @ prepare R3 print
POP {R2} @ prepare R3 print
MOV R3, R2 @ prepare R3 print
BL printf @ print R3 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #4 @ prepare R4 print
POP {R2} @ prepare R4 print
MOV R3, R2 @ prepare R4 print
BL printf @ print R4 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #5 @ prepare R5 print
POP {R2} @ prepare R5 print
MOV R3, R2 @ prepare R5 print
BL printf @ print R5 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #6 @ prepare R6 print
POP {R2} @ prepare R6 print
MOV R3, R2 @ prepare R6 print
BL printf @ print R6 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #7 @ prepare R7 print
POP {R2} @ prepare R7 print
MOV R3, R2 @ prepare R7 print
BL printf @ print R7 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #8 @ prepare R8 print
POP {R2} @ prepare R8 print
MOV R3, R2 @ prepare R8 print
BL printf @ print R8 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #9 @ prepare R9 print
POP {R2} @ prepare R9 print
MOV R3, R2 @ prepare R9 print
BL printf @ print R9 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #10 @ prepare R10 print
POP {R2} @ prepare R10 print
MOV R3, R2 @ prepare R10 print
BL printf @ print R10 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #11 @ prepare R11 print
POP {R2} @ prepare R11 print
MOV R3, R2 @ prepare R11 print
BL printf @ print R11 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #12 @ prepare R12 print
POP {R2} @ prepare R12 print
MOV R3, R2 @ prepare R12 print
BL printf @ print R12 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #13 @ prepare R13 print
POP {R2} @ prepare R13 print
MOV R3, R2 @ prepare R13 print
BL printf @ print R13 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #14 @ prepare R14 print
POP {R2} @ prepare R14 print
MOV R3, R2 @ prepare R14 print
BL printf @ print R14 value prior to reg_dump call
POP {R3} @ restore register
POP {R2} @ restore register
POP {R1} @ restore register
POP {R0} @ restore regsiter
POP {PC} @ return
.data
.balign 4
a: .skip 400
printf_str: .asciz "a[%d] = %d\n"
printf_str_min: .asciz "MINIMUM VALUE = %d\n"
printf_str_max: .asciz "MAXIMUM VALUE = %d\n"
debug_str:
.asciz "R%-2d 0x%08X %011d \n"
exit_str: .ascii "Terminating program.\n"