-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAssembly_Functions.S
executable file
·314 lines (252 loc) · 4.68 KB
/
Assembly_Functions.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
/*
* AssemblyFunctions.s
*/
.section .data
numberLength:
.long 00
formatSTR1:
.ascii "%s"
.byte 00
message1:
.ascii "First Number Please: "
.byte 00
message2:
.ascii "Second Number Please: "
.byte 00
message3:
.ascii "The result is : "
.byte 00
.text
.globl _addLarge
_addLarge:
pushl %ebp
movl %esp, %ebp
// Get first Number
lea message1,%ebx
pushl %ebx
call _printf
add $4,%esp
// The following function calls fflush(stdout)
call _flushBuffer
movl 8(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
call _getNumber
add $4, %esp
lea message2,%ebx
pushl %ebx
call _printf
add $4,%esp
// The following function calls fflush(stdout)
call _flushBuffer
// Get second number
movl 12(%ebp),%ebx
// The address of number2 is in %ebx
pushl %ebx
call _getNumber
add $4, %esp
// Add the numbers
movl 8(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
movl 12(%ebp),%ebx
// The address of number2 is in %ebx
pushl %ebx
movl 16(%ebp),%ebx
// The address of result is in %ebx
pushl %ebx
call _addNumbers
addl $12,%esp
//Print the result
lea message3,%ebx
pushl %ebx
call _printf
add $4,%esp
// The following function calls fflush(stdout)
call _flushBuffer
lea formatSTR1,%ebx
pushl %ebx
movl 16(%ebp),%ebx
pushl %ebx
call _printf
add $8,%esp
popl %ebp
ret
.section .data
mess:
.ascii "Try again please -- No spaces or nonnumeric characters allowed :"
.byte 00
.text
.align 4
.globl _getNumber
_getNumber:
pushl %ebp
movl %esp, %ebp
askAgain:
movl 8(%ebp),%ebx
// The address of number is in %ebx
pushl %ebx
lea formatSTR1,%ebx
pushl %ebx
call _scanf
add $8,%esp
movl 8(%ebp),%ebx
xorl %esi,%esi
nextChar:
cmpb $0,(%ebx,%esi,1)
je numberValid
cmpb $0x30,(%ebx,%esi,1)
jl errorMess
cmpb $0x39,(%ebx,%esi,1)
jg errorMess
inc %esi
jmp nextChar
errorMess:
lea mess,%ebx
pushl %ebx
call _printf
add $4,%esp
call _flushBuffer
jmp askAgain
numberValid:
popl %ebp
ret
_addNumbers:
// Add numbers is called with three arguments
// in the order number1, number2 and result
pushl %ebp
movl %esp, %ebp
movl 16(%ebp),%ebx
xorl %esi,%esi
cont1:
cmp $0,(%ebx,%esi,1)
jz length1
inc %esi
jmp cont1
length1:
movl 12(%ebp),%ebx
xorl %edi,%edi
cont2:
cmp $0,(%ebx,%edi,1)
jz length2
inc %edi
jmp cont2
length2:
// esi has the length of number1 and edi has the length of number2
lea numberLength,%ebx
movl %esi,(%ebx)
cmpl %esi,%edi
jg CO2
movl %edi,(%ebx)
CO2:
// numberLength has the lenght of the longer number
movl 16(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
call _rightAlign
add $4, %esp
movl 12(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
call _rightAlign
add $4, %esp
movl 16(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
call _ascii2BCD
add $4, %esp
movl 12(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
call _ascii2BCD
add $4, %esp
movl 12(%ebp),%edi
add $numberLength,%edi
// The address of number1 is in %ebx
movl 16(%ebp),%esi
add $numberLength,%esi
movl 18(%ebp),%ebx
add $numberLength,%ebx
mov $numberLength,%ecx
clc
addnextbyte:
movb (,%esi,1),%al
adcb ( ,%edi,1),%al
movb %al,(,%ebx,1)
dec %edi
dec %esi
loop addnextbyte
movl 8(%ebp),%ebx
// The address of number1 is in %ebx
pushl %ebx
call _BCD2ascii
add $4, %esp
pop %ebp
ret
.globl _ascii2BCD
_ascii2BCD:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp),%ebx
movl $numberLength,%esi
movl %esi,%ecx
back1:
and $0x0F,(%ebx,%esi,1)
dec %esi
loop back1
pop %ebp
ret
.globl _BSC2ascii
_BCD2ascii:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp),%ebx
movl $numberLength,%esi
movl %esi,%ecx
back3:
or $0x30,(%ebx,%esi,1)
dec %esi
loop back3
pop %ebp
ret
.globl _rightAlign
_rightAlign:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp),%ebx
lea numberLength,%edi
xor %ecx,%ecx
xor %esi,%esi
back2:
cmpb $0,(%ebx,%esi,1)
je endof
inc %esi
inc %ecx
jmp back2
endof:
cmp %esi,%edi
je out1
doit:
movb (%ebx,%esi,1), %al
movb %al,(%ebx,%edi,1)
dec %esi
dec %edi
loop doit
mov %edi,%ecx
zerofil:
movb $0, (%ebx,%ecx,1)
loop zerofil
out1:
pop %ebp
ret
.globl _flushBuffer
_flushBuffer:
// The following function calls fflush(stdout)
movl $0x77c5fca0,%ebx
pushl %ebx
call _fflush
addl $4,%esp
ret
.globl _printCRLF
_printCRLF:
ret