-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculator_Irvine32.asm
314 lines (236 loc) · 9.81 KB
/
calculator_Irvine32.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
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
;Calculator Program
;Date 6-12-22
INCLUDE Irvine32.inc
;TODO: Make local variable for sum and counter, add more comments, div procedure
.data
;User input variables
select dword ?
input1 dword ?
input2 dword ?
;0dh,0ah New line
;0 End of line
;Menu prompts
prompt0 byte "Select an Operation to preform:",0dh,0ah,0
prompt1 byte "1) Addition",0dh,0ah,0
prompt2 byte "2) Subtraction",0dh,0ah,0
prompt3 byte "3) Multiplication",0dh,0ah,0
prompt4 byte "4) Division",0dh,0ah,0
prompt5 byte "5) Exit",0dh,0ah,0
prompt6 byte "Enter selection: ",0
;Additional console prompts
prompt7 byte "Result: ",0
prompt8 byte "Enter a valid selection: ",0
prompt9 byte "Enter first number: ",0
prompt10 byte "Enter second number: ",0
;Array of menu prompts
arrayTexts dword prompt0, prompt1, prompt2, prompt3, prompt4, prompt5, prompt6, 0
;Pointer to arrayTexts
ptrT dword offset arrayTexts
;Make these local variables
counter dword 1 ;How to get rid of counter?
sum dword ?
.code
main proc
start:
call printMenu ;Print Menu to Console
selection:
call readInt ;Get users selection
mov select, eax ;Move user input into select variable
S1:
cmp select, 1 ;If selection != 1, jump to S2
jne S2
call getUserInput ;Get user input
call addition ;Complete Addition
jmp start ;Go back to menu
S2:
cmp select, 2 ;If selection != 2, jump to S3
jne S3
call getUserInput ;Get user input
call subtraction ;Complete Subtraction
jmp start ;Go back to menu
S3:
cmp select, 3 ;If selection != 3, jump to S4
jne S4
call getUserInput ;Get user input
call multiplication ;Complete Multiplication
jmp start ;Go back to menu
S4:
cmp select, 4 ;If selection != 4, jump to S5
jne S5
call getUserInput
call division
jmp start ;Go back to menu
S5:
cmp select, 5 ;If selection = 5, exit program
je theExit
mov ecx, offset prompt8
mov esi, lengthof prompt8
call printStr ;Inform user to enter valid selection
jmp selection ;Ask for another selection
addition proc
push ebp ;Save Registers
mov ebp,esp
;EBX = Sum (input1)
;EAX = Carry (input2)
A1:
mov eax, input1 ;Store input1 to perform XOR
xor eax, input2 ;Bitwise operation XOR performs 'add'
mov ebx, eax ;'Add' xor to Sum
mov eax, input1 ;Store input1 to preform AND
and eax, input2 ;Bitwise operation AND shows which positions need a carry
shl eax, 1 ;Shift left to check for carries
mov input1, ebx ;Store sum into input1
mov input2, eax ;Store shifted carry into input2
jnz A1 ;If a carry still exist loop again
mov ecx, offset prompt7 ;Result Text
mov esi, lengthof prompt7
call printStr
mov eax, input1 ;Store result in eax
call writeInt ;Print result
call Crlf ;New line
mov esp, ebp
pop ebp ;Restore Registers
ret
addition endp
;Subtraction is just addition with negative signs
;Ex: 6 - 3 is the same as 6 + (-3)
subtraction proc
push ebp ;Save Registers
mov ebp,esp
;Perform 2's complement on input2
xor input2, -1 ;Flip every bit in input2
inc input2 ;Increase by 1
call addition
mov esp, ebp
pop ebp ;Restore Registers
ret
subtraction endp
;Example of binary multiplication
; input1 = 5 input2 = 3
; 5 * 3 = 5 * (2^1 + 2^0) <---- Binary rep of 3 is 0011
; = 5 * (2 + 1) = (5 * 2) + (5 * 1)
; = 15
multiplication proc
push ebp ;Save Registers
mov ebp,esp
mov eax, input1 ;Move input1 (multiplicand) into eax
mov ecx, 32 ;Size of register
mov ebx, 0 ;Clear ebx register, counter
;Pushad and popad reset general registers
next:
rcr eax, 1 ;Rotate bits to right
jnc M1 ;If carry flag is 1, get position
pushad ;Store all general registers
mov ecx, ebx ;Move position of on bit into ecx
mov eax, input2 ;Move input2 (multipler) into eax
;cl is a 8 bit sub-register of ecx
shl eax, cl ;Perform bitwise multiplication by shl w/ current position
;Use addition procedure here
add sum, eax ;add current input2 * 2^cl into sum
popad ;Overwrites all general registers
M1:
inc ebx ;Current position that bit is on
loop next ;Continue to next bit
mov ecx, offset prompt7 ;Result Text
mov esi, lengthof prompt7
call printStr
mov eax, sum
call writeInt
call Crlf ;New line
mov sum, 0 ;Clear sum
mov esp, ebp
pop ebp ;Restore Registers
ret
multiplication endp
;Order matters with division, commutative property
;This procedure only works if there's no remainders or fractions
;Possible to use IEEE 754 rep?
division proc
push ebp ;Save Registers
mov ebp,esp
mov eax, input2 ;Move input1 (dividend) into eax
mov ecx, 32 ;Size of register
mov ebx, 0 ;Clear ebx register, counter
;Pushad and popad reset general registers
next:
rcr eax, 1 ;Rotate bits to right
jnc D1 ;If carry flag is 1, get position
pushad ;Store all general registers
mov ecx, ebx ;Move position of on bit into ecx
mov eax, input1 ;Move input2 (divisor) into eax
;cl is a 8 bit sub-register of ecx
shr eax, cl ;Perform bitwise division by shr w/ current position
;Use addition procedure here
add sum, eax ;add current input2 / 2^cl into sum
popad ;Overwrites all general registers
D1:
inc ebx ;Current position that bit is on
loop next ;Continue to next bit
mov ecx, offset prompt7 ;Result Text
mov esi, lengthof prompt7
call printStr
mov eax, sum
call writeInt
call Crlf ;New line
mov sum, 0 ;Clear sum
mov esp, ebp
pop ebp ;Restore Registers
ret
division endp
getUserInput proc
push ebp ;Save Registers
mov ebp,esp
mov ecx, offset prompt9 ;Ask user for first number
mov esi, lengthof prompt9
call printStr
call readInt ;Get users input and move into input variable
mov input1, eax
mov ecx, offset prompt10 ;Ask user for second number
mov esi, lengthof prompt10
call printStr
call readInt ;Get users input and move into input variable
mov input2, eax
mov esp, ebp
pop ebp ;Restore Registers
ret
getUserInput endp
printStr proc
push ebp ;Save Registers
mov ebp,esp
print:
mov al, byte ptr[ecx] ;Move Char at ecx address into al
inc ecx ;Move to next char
call writeChar ;Print char to console
cmp al, NULL ;If null terminated end loop, if not continue
jnz print
mov esp, ebp
pop ebp ;Restore Registers
ret
printStr endp
printMenu proc
push ebp ;Save Registers
mov ebp,esp
push esi
push ecx
mov esi, ptrT ;Pointer to arrayTexts
mov ecx, [esi] ;[esi] is first item in arrayTexts
;Because arrayText is an array of pointers to bytes of Text
;we need to increment to each character until the NULL terminator
;then move the esi pointer to the next element in arrayTexts
P1:
call printStr ;Print string pointer is currently at
mov ebx, counter ;Move current counter into ebx register
inc counter ;Increase the counter for next run
mov ecx, [esi+4*ebx] ;Dword is 4 bytes long, each 4 bytes is an element of arrayTexts
cmp ecx, NULL ;4*counter gives the position of current element to print
jnz P1 ;If array is null terminated, end of printing menu
mov counter, 1
pop ecx
pop esi
mov esp, ebp
pop ebp ;Restore Registers
ret
printMenu endp
theExit:
main endp
end main