This repository has been archived by the owner on Mar 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprog5.asm
277 lines (240 loc) · 7.91 KB
/
prog5.asm
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
TITLE Program 5 (prog5.asm)
; Author: Nils Streedain
; Last Modified: 2/27/2022
; OSU email address: [email protected]
; Course number/section: 271-001
; Assignment Number: 5
; Due Date: 2/27/2022
; Description: Write a MASM program to perform the tasks shown below. Be sure to test your program and ensure that it rejects incorrect input values.
; Introduce the program.
; Get a user request in the range [min = 15 .. max = 200].
; Generate request random integers in the range [lo = 100 .. hi = 999], storing them in consecutive elements of an array.
; Display the list of integers before sorting, 10 numbers per line.
; Sort the list in descending order (i.e., largest first).
; Calculate and display the median value, rounded to the nearest integer.
; Display the sorted list, 10 numbers per line.
INCLUDE Irvine32.inc
; constants
MIN = 15
MAX = 200
LO = 100
HI = 999
.data
; interface strings
intro BYTE "Sorting Random Integers", 13, 10, "Programmed by Nils Streedain", 13, 10, "This program generates random numbers in the range [100 .. 999],", 13, 10, "displays the original list, sorts the list, and calculates the", 13, 10, "median value. Finally, it displays the list sorted in descending order.", 13, 10, "**EC: Random TA Name: Megan Black", 13, 10, 0
prompt BYTE "How many numbers should be generated? [15 .. 200]: ", 0
error BYTE "Invalid input", 13, 10, 0
unsortTitle BYTE "The unsorted random numbers:", 13, 10, 0
medTitle BYTE 13, 10, "The median is ", 0
sortTitle BYTE ".", 13, 10, "The sorted list:", 13, 11, 0
bye BYTE 13, 10, "Thanks for using my program!", 0
; program variables
request DWORD ?
list DWORD MAX DUP(?)
.code
main PROC
push OFFSET intro
call introduction ; Prints the program title, author's name, & extra credit tag.
push OFFSET prompt
push OFFSET error
push OFFSET request
call getData ; Repeatedly prompts the user for a number until one is given between MIN & MAX.
call Randomize ; Makes sure different random numbers are generated each time.
push OFFSET list
push request
call fillArray ; Fills the array with randomly generated numbers between HI & LO.
push OFFSET list
push request
push OFFSET unsortTitle
call displayList ; Prints a string representation of the unsorted array to the console
push OFFSET list
push request
call sortList ; Sorts the array usinging selection sort
push OFFSET list
push request
push OFFSET medTitle
call displayMedian ; Prints the median element to the console
push OFFSET list
push request
push OFFSET sortTitle
call displayList ; Prints a string representation of the sorted array to the console
push OFFSET bye
call introduction ; tells the user goodbye
exit ; exit to operating system
main ENDP
; Description: Prints the program title, author's name, extra credit stats, & instructions
; Receives: [ebp + 8]: Introduction string
; Returns: N/A
; Preconditions: string must be pushed
; Register changed: edx
introduction PROC
push ebp
mov ebp, esp
mov edx, [ebp + 8] ; intro
call WriteString
pop ebp
ret 4
introduction ENDP
; Description: Repeatedly prompts the user for a number until the user inputs a valid integer between LO & HI
; Receives: [ebp + 16]: Prompt string, [ebp + 12]: Error string, [ebp + 8]: request
; Returns: Number input by user to request
; Preconditions: Prompt, Error, & request must be given
; Register changed: eax, ebx, edx
getData PROC
push ebp
mov ebp, esp
promptUser:
mov edx, [ebp + 16] ; prompt string
call WriteString
call ReadInt
cmp eax, MIN ; validate input is between min & max
jl outOfRange ; if invalid, outOfRange is called
cmp eax, MAX
jg outOfRange
jmp valid
outOfRange: ; prints error, asks for new input
mov edx, [ebp + 12] ; error string
call WriteString
jmp promptUser
valid: ; returns when valid number is given
mov ebx, [ebp + 8] ; request int
mov [ebx], eax
pop ebp
ret 12
getData ENDP
; Description: Fills the given array with random number values between LO & HI
; Receives: [ebp + 8]: Length, [ebp + 12]: Array
; Returns: Array filled with random numbers
; Preconditions: Array & length must be provided
; Register changed: eax, ecx, esi
fillArray PROC
push ebp
mov ebp, esp
mov ecx, [ebp + 8] ; num times to loop
mov esi, [ebp + 12] ; list ref
fillLoop:
mov eax, HI
sub eax, LO
inc eax ; find difference between LO & HI
call RandomRange
add eax, LO ; find random int between LO & HI
mov [esi], eax ; insert into array
add esi, 4
loop fillLoop ; loop over every array element
pop ebp
ret 8
fillArray ENDP
; Description: Sorts the given number array from largest to smallest
; Receives: [ebp + 8]: Array, [ebp + 12]: Length
; Returns: Sorted array in array
; Preconditions: Array must contain number elements & length must be the length of array
; Register changed: eax, ebx, ecx, edx, esi
sortList PROC
push ebp
mov ebp, esp
mov ecx, [ebp + 8] ; num times to loop
mov esi, [ebp + 12] ; list ref
iterateLoop:
mov edx, esi ; store esi to edx to change in swapLoop
push ecx ; push counter for swapLoop
sub edx, 4
swapLoop:
add edx, 4
mov eax, [esi] ; curr
mov ebx, [edx] ; next
cmp eax, ebx
jg noSwap ; if curr is greater than next, don't swap
push esi
push edx
call exchange ; swap pushed addresses
noSwap:
loop swapLoop
pop ecx
add esi, 4
loop iterateLoop
pop ebp
ret 8
sortList ENDP
; Description: Swaps to elements in a number array using their given addresses
; Receives: [ebp + 8]: Addr1, [ebp + 12]: Addr2
; Returns: Val of Addr1 in Addr2 and val of Addr2 in Addr1
; Preconditions: Addr must be valid addresses to elements in an array
; Register changed: eax, ebx, ecx, edx
exchange PROC
push ebp
mov ebp, esp
pushad
mov eax, [ebp + 8] ; item 1 addr
mov ebx, [ebp + 12] ; item 2 addr
mov ecx, [eax] ; item 1 value
mov edx, [ebx] ; item 2 value
mov [ebx], ecx ; put item 1 value in item 2 addr
mov [eax], edx ; put item 2 value in item 1 addr
popad
pop ebp
ret 8
exchange ENDP
; Description: Finds & prints the median element of an array
; Receives: [ebp + 8]: Title, [ebp + 12]: Length, [ebp + 16]: Array
; Returns: N/A
; Preconditions: Array must contain number elements & length must be the length of the array
; Register changed: eax, ebx, ecx, edx, esi
displayMedian PROC
push ebp
mov ebp, esp
mov edx, [ebp + 8]
call WriteString ; prints median text
mov esi, [ebp + 16] ; array
mov eax, [ebp + 12] ; length
mov ebx, 2
cdq
div ebx
mov ecx, edx ; Move remainder to ecx so edx is clear for mul
mov ebx, 4
mul ebx ; multiply by to to find middle address
cmp ecx, 0 ; checks if length is even by seeing if it's divisible by 2
je isEven
mov eax, [esi + eax]; when length is odd, median is 1/2 the length
jmp medCalculated
isEven:
mov ebx, [esi + eax] ; find lower median
sub eax, 4
mov eax, [esi + eax] ; fina upper median
add eax, ebx
mov ebx, 2
div ebx ; calc average of medians
medCalculated:
call WriteDec ; length divided in last step, just need to calc address
pop ebp
ret 16
displayMedian ENDP
; Description: Prints a string representation of a given array
; Receives: [ebp + 8]: Title, [ebp + 12]: Length, [ebp + 16]: Array
; Returns: N/A
; Preconditions: Length must be the length of the array
; Register changed: eax, ebx, ecx, edx, esi, al
displayList PROC
push ebp
mov ebp, esp
mov edx, [ebp + 8] ; print title
call WriteString
mov ecx, [ebp + 12] ; num times to loop
mov esi, [ebp + 16] ; list ref
mov ebx, 0 ; newline counter
displayLoop:
mov eax, [esi]
call WriteDec ; print next array element
mov al, 9
call WriteChar ; print tab
inc ebx
cmp ebx, 10
jl noNewLine
call Crlf
mov ebx, 0 ; new line every 10 elements
noNewLine:
add esi, 4
loop displayLoop ; loop over length of array
pop ebp
ret 12
displayList ENDP
END main