-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinal.s
436 lines (355 loc) · 11.9 KB
/
final.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
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# This program generates a random digit number with unique digits given a
# length value input by the user (sized values of 1 to 9), and asks the user
# to try to guess the generated number. For every digit the guess shares with the generated
# number, the program prints the word Pico, but if the digit is in the same locations, it prints
# Fermi. If no digits are shared, the program prints Bagel. If the user gives up they can input
# 0 and the program will show them the generated value, along with the number of times
# the user guessed incorrently.
# By Alex Plaza
.data
.align 2
init1: .asciiz "The computer has generated a "
init2: .asciiz " digit random number with unique digits. Try to guess it, or input 0 to give up \n"
getLength: .asciiz "Select length of target b/w 1-9: "
iPrompt: .asciiz "Please enter your guess: "
Fermi: .asciiz "Fermis"
Pico: .asciiz "Pico"
Bagel: .asciiz "Bagel"
win: .asciiz "You Won!!"
newLine: .asciiz "\n"
targetp: .asciiz "Target Was: "
counter: .asciiz "Guesses: "
targetArray: .word 0,0,0,0,0,0,0,0,0
guessArray: .word 0,0,0,0,0,0,0,0,0
guessCounter: .word 0
.text
.globl main
main:
lw $s5, guessCounter #s5 = guessCounter: counts the number of guesses
la $a0, getLength
li $v0, 4
syscall # print message to get length from user
li $v0, 5
syscall
move $t9, $v0 # move user input into t9
la $a0, targetArray # a0 = address of the targetArray
move $a1, $t9 # a1 = length
jal GenerateNumber # GenerateNumber(targetArray, length)
move $s7, $v0 #s7 = TargetNumber (NOT THE ARRAY, BUT THE ACTUAL NUMBER)
la $a0, init1 #print initial message
li $v0, 4
syscall
move $a0, $t9 #print length
li $v0, 1
syscall
la $a0, init2
li $v0, 4
syscall
#Uncomment the code below to "cheat" and see the generated number before start guessing#
#move $a0, $t9
#la $a1, targetArray
#jal printList
#la $a0, newLine
#li $v0, 4
#syscall
game:
move $a0, $s7
la $a1, guessArray
move $a2, $t9
jal getInput #getInput(generatedNumber, addressGuessArray, length)
la $a0, targetArray
la $a1, guessArray
move $a2, $t9
jal CompareArrays #CompareArrays(addressTargetArray, addressGuessArray, length)
j game
#----------------------------------------- GenerateNumber --------------------------------------------#
# The function GenerateNumber takes as a parameter the array where the generated number will be stored.
# It generates a random number b/t 10*length*1 and 10*length*9 using syscall 42 (i.e. if length = 4 then
# the generated number is between 1000-9990). Then, it separates the digits in the generated number
#and stores them in the array that was passed as a parameter. Then it checks if the digits of the number
# are unique, if they are not, it generates a random number again. At the end the function will return
# the generated number, and the digits of generated number will be in the array passed.
GenerateNumber:
######### Allocate Stack Space #########
addi $sp, $sp, -12 # allocate stack space for 3 values
sw $ra, 0($sp)
sw $s3, 4($sp)
sw $s4, 8($sp)
######### Init variables #########
move $s3, $a0 #s3 = array address
move $s4, $a1 #s4 = length or array
move $t8, $0 #t8-t1 auxiliary variables used for intermidiate calculations.
move $t7, $0
move $t5, $0
move $t4, $0
move $t3, $0
move $t1, $0
GenerateRandom:
######### Generate Random Number #########
move $t0 , $s4 #t0 = i
li $t7, 1 # lower bound for random
li $a1, 8 # upper bound for random
CreateLimit:
beq $t0, 1, generate # if i != 1
mul $a1, $a1, 10 # mul lupper bound by 10
mul $t7, $t7, 10 # mul lowe bound by 10
addi $t0, $t0, -1 # i--
j CreateLimit
generate:
li $v0, 42 #generates random number and places it in a0
syscall
add $t8, $a0, $t7 #t8 = target number
move $a0, $t8
la $a1, ($s3)
move $a2, $s4
jal SeparateNumbers #SeparateNumbers(generatedNumber, addressTargetArray, length)
move $t6, $0 # i = 0
move $t2, $0
addi $t2, $t2, 1 #j = 1
UniqueLoop: #check if generated number has unique digits
bge $t6, $s4, EndUnique # if i < length
sll $t5, $t6, 2
add $t4, $s3, $t5
lw $t3, 0($t4) #t3 = array[i]
InnerUnique:
bge $t2, $s4, EndInnerUnique # if j < length
sll $t5, $t2, 2
add $t4, $s3, $t5
lw $t1, 0($t4) #t1 = array[j]
beq $t1, $t3, GenerateRandom # if array[i] = array[j]
addi $t2, $t2, 1
j InnerUnique
EndInnerUnique:
addi $t6, $t6, 1 # i++
addi $t2, $t6, 1 # j = i+1
j UniqueLoop
EndUnique:
######### Prepare Return Values #########
move $v0, $t8 # move generated number to retun register
######### Restore Stack Space #########
lw $ra, 0($sp)
lw $s3, 4($sp)
lw $s4, 8($sp)
addi $sp, $sp, 12
jr $ra
#----------------------------------------- SeparateNumber --------------------------------------------#
# The SeparateNumbers function takes as parameters a number, an array address, and the length of the
# array. The function separates the digits of the number using modulos and divisions, and stores
# the digits in the provided array.
SeparateNumbers:
######### Allocate Stack Space #########
addi $sp, $sp, -16 # allocate stack space for 4 values
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
######### Init variables #########
move $s0, $a0 #s0 = number to split
move $s1, $a1 #s1 = address of array
move $s2, $a2 #s2 = length
li $t0, 1 #t0-t4 auxiliary variables used for intermidiate calculations.
li $t1, 10
move $t2, $0
move $t3, $0
move $t4, $0
move $t5, $s2
addi $t5, $t5, -1 #t5 = index = length - 1
######### Separate Numbers #########
SeparateLoop:
blt $t5, 0, EndSeparate # if index >= 0
div $s0, $t1
mfhi $t2 #t2 = s0 % t1
div $t2, $t0
mflo $t3 #t3 = t2/t0 (integer division) --> ith digit
sll $t4, $t5, 2
add $t6, $s1, $t4 # t6: get offset for array[index*4]
sw $t3, 0($t6) # Store digit t3 in array[index*4]
addi $t5, $t5, -1 # i--
mul $t0, $t0, 10
mul $t1, $t1, 10
j SeparateLoop
EndSeparate:
######### Restore Stack Space #########
lw $ra, 0($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $s2, 12($sp)
addi $sp, $sp, 16
jr $ra
#----------------------------------------- getInput --------------------------------------------#
# getInput takes as a a parameter the target number and the address of the guessArray. It prompts
# the user to input a guess, then it increases the guess counter, then if the target is equal to
# the guess, go to Win, and if the target is the special input 0 go to Terminate. Otherwise,
# separate the digits of the guess number and store the digits in the provided array.
getInput:
######### Allocate Stack Space #########
addi $sp, $sp, -16 # allocate stack space for 3 values
sw $ra, 0($sp)
sw $s7, 4($sp)
sw $s6, 8($sp)
sw $s4, 12($sp)
######### Init variables #########
move $s4, $a2 #s4 = length
move $s6, $a1 # s6 = guessArray
move $s7, $a0 # s7 = target number
move $t5, $0 # t5-t6 = auxiliary variables used for intermidiate operations
move $t6, $0
######### Print prompt and get guess from user #########
la $a0, iPrompt
li $v0, 4
syscall # print please input guess
li $v0, 5
syscall
move $t6, $v0 #t6 = guess
addi $s5, $s5, 1 #guessCounter++
beq $t6, $s7, Win # if the targetNumber and guessNumber are equal go to Win
beq $t6, 0, Terminate # if input is 0 go to Terminate
j SeparateGuess # if none of the beq above are true,
# continue to separate the digits in guess
######### Print Win Message #########
Win:
la $a0, win
li $v0, 4
syscall # print you Won!!
la $a0, newLine # print new line
li $v0, 4
syscall
la $a0, counter #guesses:
li $v0, 4
syscall
move $a0, $s5 #print guessCounter
li $v0, 1
syscall
li $v0 10
syscall
######### Print Terminate Message #########
Terminate:
addi $s5, $s5, -1
la $a0, targetp #print target was:
li $v0, 4
syscall
move $a0, $s4
la $a1, targetArray
jal printList #printList(length, addressTargetArray)
la $a0, newLine # print new line
li $v0, 4
syscall
la $a0, counter #guesses:
li $v0, 4
syscall
move $a0, $s5 #print guessCounter
li $v0, 1
syscall
li $v0 10
syscall
SeparateGuess:
######### Separate digits in guess #########
move $a0, $t6
move $a1, $s6
move $a2, $s4
jal SeparateNumbers #SeparateNumbers(guessedNumber, guessArray, length)
######### Restore Memory #########
lw $ra, 0($sp)
lw $s7, 4($sp)
lw $s6, 8($sp)
lw $s4, 12($sp)
addi $sp, $sp, 16
jr $ra
#----------------------------------------- CompareArrays --------------------------------------------#
# The function ComapareArrays takes as parametes two arrays, and the length of the arrays (it assumes
# the leght of both arrays is equivalent). It compares the two arrays using two loops. Each number
# of array1 is compared with each number of array 2. If, any of the number are the same, generate
# a message accordingly. If the comparison is over and no picos or fermis were printed, print bagel.
CompareArrays:
######### Allocate Stack Space #########
addi $sp, $sp, -12 # allocate stack space for 3 values
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
######### init Variables #########
move $s0, $a0 #s0 = array1
move $s1, $a1 #s1 = array2
move $s2, $a2 #s2 = lenght
move $t3, $0 #t3 = Fermis and Pico Counter
move $t4, $0 #t4 = aux = 0
move $t6, $0 #t6 = aux = 0
move $t7, $0 #t7 = i = 0
move $t5, $0 #t5 = j = 0
######### Compare Numbers #########
CompareLoop:
bge $t7, $s2, EndCompare # if i < length
sll $t6, $t7, 2
add $t4, $s0, $t6
lw $t0, 0($t4) #t0 = array1[i]
Inner:
bge $t5, $s2, EndInner # if j < length
sll $t6, $t5, 2
add $t4, $s1, $t6
lw $t1, 0($t4) #t1 = array2[i]
beq $t0, $t1, generateMessage # if array[i] = array[j] generate a message.
addi $t5, $t5, 1
j Inner
######### Generate Message #########
generateMessage:
addi $t3, $t3, 1 #Fermis&PicoCounter++
beq $t7, $t5, printFermi # if i = j
######### Print Pico #########
la $a0, Pico
li $v0, 4
syscall
addi $t5, $t5, 1
la $a0, newLine
li $v0, 4
syscall
j Inner
######### Print Fermi #########
printFermi:
la $a0, Fermi
li $v0, 4
syscall
addi $t5, $t5, 1
la $a0, newLine
li $v0, 4
syscall
j Inner
######### Print Bagel #########
PrintBagel:
la $a0, Bagel
li $v0, 4
syscall
la $a0, newLine
li $v0, 4
syscall
j afterBagel
######### End Inner loop and Restart outer loop #########
EndInner:
move $t5, $0 # restart inner loop j = 0
addi $t7, $t7, 1 # j++
j CompareLoop
######### Print Bagel if necessary, and end function #########
EndCompare:
beqz $t3, PrintBagel #if no picos or fermis were printer, print bagel
afterBagel:
######### Restore Stack Space #########
lw $ra, 0($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
addi $sp, $sp, 12
jr $ra
#----------------------------------------- printList --------------------------------------------#
# Function printList take as parameters the length of the array and its address and loops over the
# elements and prints them one by one. No need to allocate stack space since this function isn't
# using s register.
printList:
move $t0, $0 #t0: index i = 0
move $t1, $a0 #t1: arryLength
move $t2, $a1 #t2: Address
printLoop: bge $t0, $t1, endPrint # if i < arrayLength
lw $a0, 0($t2) # print element
li $v0, 1
syscall
addi $t0, $t0, 1 # ++i
addi $t2, $t2, 4 # Address = address + 4
j printLoop
endPrint:
jr $ra