-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathast.asm
313 lines (253 loc) · 9.54 KB
/
ast.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
section .data
delim db " ", 0
section .bss
root resd 1
current_node resd 1
is_operator resd 1
is_negative_atoi resd 1
section .text
extern evaluate_ast
extern create_node
extern malloc
extern strdup
global create_tree
global iocla_atoi
iocla_atoi: ;change string to number
enter 0, 0
push ebx ;saving callee registers
mov eax, [ebp + 8]
xor ecx, ecx ;stores the result
xor ebx, ebx ;stores character
mov edx, 0
mov [is_negative_atoi], edx ;the default way is that the number is positive
;we check to see if the number is negative or not
mov bl, [eax]
cmp bl, '-' ;compare to minus character
jnz atoi_loop ;if it is not a minus sign just do the rest as usual
mov edx, 1
mov [is_negative_atoi], edx ;change global variable
inc eax ;get rid of the minus
atoi_loop:
mov bl, [eax] ;get the character
test bl, bl ;check if we reached the end
jz end_of_atoi
imul ecx, 0xa ;multiply ecx by 10
sub bl, '0'
add ecx, ebx
inc eax
jmp atoi_loop
end_of_atoi:
;checking to see if the number was negative or not
mov eax, ecx
mov edx, [is_negative_atoi]
cmp edx, 0
jz is_positive_number
;we do the next only of the number is negative
mov eax, 0
sub eax, ecx
is_positive_number:
pop ebx ;restoring callee registers
leave
ret
replace_next_white_char: ;replaces next space character with '\0'
;returns a pointer to the word after the space, or
;a 0 if this word was the last one (in ebx)
enter 0, 0
mov ebx, [ebp + 8] ; the parameter is a string
starting_loop:
mov cl, [ebx]
cmp cl, [delim]
jz end_of_replacement ;we have found a space, going to replace it
cmp cl, 0
jz last_word_case ;we have foudn a '\0' char, this is the last word
inc ebx;
jmp starting_loop
end_of_replacement:
mov cl, 0
mov [ebx], cl ;replace the space character with a '\0'
inc ebx ;return the value after the '\0'
jmp end_of_replacement_function
last_word_case:
mov ebx, 0 ;return 0 in ebx
end_of_replacement_function:
leave
ret
check_if_operator: ;check is the symbol given parameter is an operator
;(+,-,*,/), store the information in "is_operator"
enter 0, 0
push ebx
mov eax, [ebp + 8] ;puttin into ecx the string
mov cl, [eax] ;putting into cl the first character of the string
cmp cl, '+'
jz is_an_operator
cmp cl, '-'
jz is_a_minus ;it could either a operator or a negative number
cmp cl, '*'
jz is_an_operator
cmp cl, '/'
jz is_an_operator
mov ebx, 0x0 ; it is not an operator
mov [is_operator], ebx
jmp end
is_a_minus:
mov cl, [eax + 0x1] ;get the second character
cmp cl, 0 ;if the next char is '\0' is an operator
jz is_an_operator
mov ebx, 0x0 ; it is not an operator
mov [is_operator], ebx
jmp end
is_an_operator:
mov ebx, 0x1
mov [is_operator], ebx
end:
pop ebx
leave
ret
create_tree:
enter 0, 0
push ebx ;saving registers
mov edx, [ebp + 8]
push eax ;saving eax register
push ecx ;saving ecx register
push edx ;pushing parameter
call replace_next_white_char
pop edx ;removing paramter
pop ecx ;restoring ecx register
pop eax ;restoring eax register
;initializing root Node
push ebx ;saving ebx register
push ecx ;saving ecx register
push edx ;saving edx register
push edx ;save edx register for malloc
push 0xc
call malloc ;allocate space for structure
add esp, 0x4
pop edx ;restore edx register from malloc
push eax ;save eax
push edx
call strdup ;duplicate node value
add esp, 0x4
mov edx, eax
pop eax ;restore eax with node address
mov [eax], edx ;set value field
mov [eax + 0x4], DWORD 0 ;set left to null
mov [eax + 0x8], DWORD 0 ;set right to null
pop edx ;restoring edx register
pop ecx ;restoring ecx register
pop ebx ;restoring ebx register
mov [root], eax; ;initialize the root
mov [current_node], eax ;initialize the current_node for the first time
push eax; ;push first node to stack
traverse_token:
cmp ebx, 0 ;the previous word was the last one
jz reached_end_token;
mov edx, ebx ;move edx to the next word and call the function that
;puts a '\0' tot the end of it
push eax ;saving eax register
push ecx ;saving ecx register
push edx ;pushing parameter
call replace_next_white_char
add esp, 0x4 ;removing paramter
pop ecx ;restoring ecx register
pop eax ;restoring eax register
;create node
push ebx ;saving ebx register
push ecx ;saving ecx register
push edx ;saving edx register
push edx ;save edx register for malloc
push 0xc
call malloc ;allocate space for structure
add esp, 0x4
pop edx ;restore edx register from malloc
push eax ;save eax
push edx
call strdup ;duplicate node value
add esp, 0x4
mov edx, eax
pop eax ;restore eax with node address
mov [eax], edx ;set value field
mov [eax + 0x4], DWORD 0 ;set left to null
mov [eax + 0x8], DWORD 0 ;set right to null
pop edx ;restoring edx register
pop ecx ;restoring ecx register
pop ebx ;restoring ebx register
push eax ;saving eax register
push ebx ;saving ebx register
push ecx ;saving ecx register
push edx ;pushing parameter
call check_if_operator
add esp, 0x4 ;removing parameter
pop ecx ;restoring ecx register
pop ebx ;restoring ebx register
pop eax ;restoring eax register
mov ecx, [is_operator];
cmp ecx, 0x1
je things_to_do_if_operator ;it is an operator
jmp things_to_do_if_not_operator ;it is not an operator
things_to_do_if_operator:
push eax
;now we add the eax node either to the left or right of current_node
;if left is null, add to left; if left is not null, add to right and change
;current_node to parrent node
mov ecx, [current_node] ;move to ecx the node
mov ecx, [ecx + 0x4] ;move to ecx the left node address
cmp ecx, 0x0 ;check if it si null
jz add_to_left_operator
jmp add_to_right_operator
; DONE
things_to_do_if_not_operator:
;NO need to push eax because integer values are always leafs
;we add the eax node either to the left or right, if we add to the right
;the current_node is updated by poping the stack
mov ecx, [current_node] ;move to ecx the node
mov ecx, [ecx + 0x4] ;move to ecx the left node address
cmp ecx, 0x0 ;check if it si null
jz add_to_left_value
jmp add_to_right_value
; DONE
end_of_operator_actions:
jmp traverse_token ;iterate for next character
add_to_left_operator:
mov ecx, [current_node] ;move to ecx the node
mov [ecx + 0x4], eax ;left value is updated
mov [current_node], eax ;current_node is updated to the inserted value
jmp end_of_operator_actions ;TBDT
add_to_right_operator: ;adding to the right for operators
mov ecx, [current_node] ;move to ecx the node
mov [ecx + 0x8], eax ;right value is updated
mov [current_node], eax ;current_node is updated to the inserted value
jmp end_of_operator_actions ;TBDT
add_to_left_value:
mov ecx, [current_node] ;move to ecx the node
mov [ecx + 0x4], eax ;left value is updated
jmp end_of_operator_actions ;TBDT
add_to_right_value: ;adding to the right for integer values
mov ecx, [current_node] ;move to ecx the node
mov [ecx + 0x8], eax ;right value is updated
;now current_node becomes the value in the stack that has a free right spot
;we are going to check for ecx, and when we find the value, we stop
loop_for_current_node:
pop ecx ;pop the parrent node of value
mov ecx, [esp] ;mov to ecx the future current_node without poping
mov [current_node], ecx ;update current_node to future current_node
;now we test to see if current_node(ecx) has a free right
mov ecx, [ecx + 0x8] ;move to ecx the right value
cmp ecx , 0x0 ;check if right tree is null
jz we_have_found_currNode
jmp loop_for_current_node
we_have_found_currNode:
jmp end_of_operator_actions ;TBDT
reached_end_token:
;now we should pop the remaining stack nodes that we have pushed
;we pop everytime into the current_node and do that until current_node = ebp
loop_for_poping_remaining_nodes:
mov ecx, ebp
sub ecx, esp
sub ecx, 0x4
jz very_end ;reached the bottom of the stack, the frame pointer
add esp, 0x4 ;pop node into ecx (we do nothing with it)
very_end:
mov eax, [root] ;put in eax the root
pop ebx
leave
ret