Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2287 | heavyiron | 1 | |
2 | ; Copyright (c) 1999-2012, Tomasz Grysztar. |
||
2664 | dunkaist | 3 | ; All rights reserved. |
2287 | heavyiron | 4 | |
5 | |||
6 | push ebp |
||
7 | call get_fp_value |
||
8 | jnc fp_expression |
||
9 | mov [current_offset],esp |
||
10 | expression_loop: |
||
11 | push edi |
||
12 | mov edi,single_operand_operators |
||
13 | call get_operator |
||
14 | pop edi |
||
15 | or al,al |
||
16 | jz expression_element |
||
17 | cmp al,82h |
||
2664 | dunkaist | 18 | je expression_loop |
19 | push eax |
||
2287 | heavyiron | 20 | jmp expression_loop |
21 | expression_element: |
||
22 | mov al,[esi] |
||
23 | cmp al,1Ah |
||
24 | je expression_number |
||
25 | cmp al,22h |
||
26 | je expression_number |
||
27 | cmp al,'(' |
||
28 | je expression_number |
||
29 | mov al,'!' |
||
30 | stos byte [edi] |
||
31 | jmp expression_operator |
||
32 | expression_number: |
||
33 | call convert_number |
||
34 | expression_operator: |
||
35 | push edi |
||
36 | mov edi,operators |
||
37 | call get_operator |
||
38 | pop edi |
||
39 | or al,al |
||
40 | jz expression_end |
||
41 | operators_loop: |
||
42 | cmp esp,[current_offset] |
||
43 | je push_operator |
||
44 | mov bl,al |
||
45 | and bl,0F0h |
||
46 | mov bh,byte [esp] |
||
47 | and bh,0F0h |
||
48 | cmp bl,bh |
||
49 | ja push_operator |
||
50 | pop ebx |
||
51 | mov byte [edi],bl |
||
52 | inc edi |
||
53 | jmp operators_loop |
||
54 | push_operator: |
||
55 | push eax |
||
56 | jmp expression_loop |
||
57 | expression_end: |
||
58 | cmp esp,[current_offset] |
||
59 | je expression_converted |
||
60 | pop eax |
||
61 | stos byte [edi] |
||
62 | jmp expression_end |
||
63 | expression_converted: |
||
64 | pop ebp |
||
65 | ret |
||
66 | fp_expression: |
||
67 | mov al,'.' |
||
68 | stos byte [edi] |
||
69 | mov eax,[fp_value] |
||
70 | stos dword [edi] |
||
71 | mov eax,[fp_value+4] |
||
72 | stos dword [edi] |
||
73 | mov eax,[fp_value+8] |
||
74 | stos dword [edi] |
||
75 | pop ebp |
||
76 | ret |
||
77 | |||
78 | |||
79 | lea eax,[edi-10h] |
||
80 | mov edx,[memory_end] |
||
81 | cmp [source_start],0 |
||
82 | je check_memory_for_number |
||
83 | mov edx,[labels_list] |
||
84 | check_memory_for_number: |
||
85 | cmp eax,edx |
||
86 | jae out_of_memory |
||
87 | mov eax,esp |
||
88 | sub eax,100h |
||
89 | jc stack_overflow |
||
90 | cmp eax,[stack_limit] |
||
91 | jb stack_overflow |
||
92 | cmp byte [esi],'(' |
||
93 | je expression_value |
||
94 | inc edi |
||
95 | call get_number |
||
96 | jc symbol_value |
||
97 | or ebp,ebp |
||
98 | jz valid_number |
||
99 | mov byte [edi-1],0Fh |
||
100 | ret |
||
101 | valid_number: |
||
102 | cmp dword [edi+4],0 |
||
103 | jne qword_number |
||
104 | cmp word [edi+2],0 |
||
105 | jne dword_number |
||
106 | cmp byte [edi+1],0 |
||
107 | jne word_number |
||
108 | byte_number: |
||
109 | mov byte [edi-1],1 |
||
110 | inc edi |
||
111 | ret |
||
112 | qword_number: |
||
113 | mov byte [edi-1],8 |
||
114 | add edi,8 |
||
115 | ret |
||
116 | dword_number: |
||
117 | mov byte [edi-1],4 |
||
118 | scas dword [edi] |
||
119 | ret |
||
120 | word_number: |
||
121 | mov byte [edi-1],2 |
||
122 | scas word [edi] |
||
123 | ret |
||
124 | expression_value: |
||
125 | inc esi |
||
126 | push [current_offset] |
||
127 | call convert_expression |
||
128 | pop [current_offset] |
||
129 | lods byte [esi] |
||
130 | cmp al,')' |
||
131 | jne invalid_expression |
||
132 | ret |
||
133 | symbol_value: |
||
134 | cmp [source_start],0 |
||
135 | je preprocessor_value |
||
136 | push edi |
||
137 | mov edi,address_registers |
||
138 | call get_operator |
||
139 | or al,al |
||
140 | jnz register_value |
||
141 | mov edi,directive_operators |
||
142 | call get_operator |
||
143 | pop edi |
||
144 | or al,al |
||
145 | jnz broken_value |
||
146 | lods byte [esi] |
||
147 | cmp al,1Ah |
||
148 | jne invalid_value |
||
149 | lods byte [esi] |
||
150 | movzx ecx,al |
||
151 | call get_label_id |
||
152 | store_label_value: |
||
153 | mov byte [edi-1],11h |
||
154 | stos dword [edi] |
||
155 | ret |
||
156 | broken_value: |
||
157 | mov eax,0Fh |
||
158 | jmp store_label_value |
||
159 | register_value: |
||
160 | pop edi |
||
161 | mov byte [edi-1],10h |
||
162 | stos byte [edi] |
||
163 | ret |
||
164 | preprocessor_value: |
||
165 | dec edi |
||
166 | cmp [hash_tree],0 |
||
167 | je invalid_value |
||
168 | lods byte [esi] |
||
169 | cmp al,1Ah |
||
170 | jne invalid_value |
||
171 | lods byte [esi] |
||
172 | mov cl,al |
||
173 | mov ch,10b |
||
174 | call get_preprocessor_symbol |
||
175 | jc invalid_value |
||
176 | push esi |
||
177 | mov esi,[edx+8] |
||
178 | push [current_offset] |
||
179 | call convert_expression |
||
180 | pop [current_offset] |
||
181 | pop esi |
||
182 | ret |
||
183 | |||
184 | |||
185 | xor ebp,ebp |
||
186 | lods byte [esi] |
||
187 | cmp al,22h |
||
188 | je get_text_number |
||
189 | cmp al,1Ah |
||
190 | jne not_number |
||
191 | lods byte [esi] |
||
192 | movzx ecx,al |
||
193 | mov [number_start],esi |
||
194 | mov al,[esi] |
||
195 | cmp al,'$' |
||
196 | je number_begin |
||
197 | sub al,30h |
||
198 | cmp al,9 |
||
199 | ja invalid_number |
||
200 | number_begin: |
||
201 | mov ebx,esi |
||
202 | add esi,ecx |
||
203 | push esi |
||
204 | dec esi |
||
205 | mov dword [edi],0 |
||
206 | mov dword [edi+4],0 |
||
207 | cmp byte [ebx],'$' |
||
208 | je pascal_hex_number |
||
209 | cmp word [ebx],'0x' |
||
210 | je get_hex_number |
||
211 | mov al,[esi] |
||
212 | dec esi |
||
213 | cmp al,'h' |
||
214 | je get_hex_number |
||
215 | cmp al,'b' |
||
216 | je get_bin_number |
||
217 | cmp al,'d' |
||
218 | je get_dec_number |
||
219 | cmp al,'o' |
||
220 | je get_oct_number |
||
221 | cmp al,'H' |
||
222 | je get_hex_number |
||
223 | cmp al,'B' |
||
224 | je get_bin_number |
||
225 | cmp al,'D' |
||
226 | je get_dec_number |
||
227 | cmp al,'O' |
||
228 | je get_oct_number |
||
229 | inc esi |
||
230 | get_dec_number: |
||
231 | mov ebx,esi |
||
232 | mov esi,[number_start] |
||
233 | get_dec_digit: |
||
234 | cmp esi,ebx |
||
235 | ja number_ok |
||
236 | cmp byte [esi],27h |
||
237 | je next_dec_digit |
||
238 | xor edx,edx |
||
239 | mov eax,[edi] |
||
240 | shld edx,eax,2 |
||
241 | shl eax,2 |
||
242 | add eax,[edi] |
||
243 | adc edx,0 |
||
244 | add eax,eax |
||
245 | adc edx,edx |
||
246 | mov [edi],eax |
||
247 | mov eax,[edi+4] |
||
248 | add eax,eax |
||
249 | jc dec_out_of_range |
||
250 | add eax,eax |
||
251 | jc dec_out_of_range |
||
252 | add eax,[edi+4] |
||
253 | jc dec_out_of_range |
||
254 | add eax,eax |
||
255 | jc dec_out_of_range |
||
256 | add eax,edx |
||
257 | jc dec_out_of_range |
||
258 | mov [edi+4],eax |
||
259 | movzx eax,byte [esi] |
||
260 | sub al,30h |
||
261 | jc bad_number |
||
262 | cmp al,9 |
||
263 | ja bad_number |
||
264 | add [edi],eax |
||
265 | adc dword [edi+4],0 |
||
266 | jc dec_out_of_range |
||
267 | next_dec_digit: |
||
268 | inc esi |
||
269 | jmp get_dec_digit |
||
270 | dec_out_of_range: |
||
271 | cmp esi,ebx |
||
272 | ja dec_out_of_range_finished |
||
273 | lods byte [esi] |
||
274 | cmp al,27h |
||
275 | je bad_number |
||
276 | sub al,30h |
||
277 | jc bad_number |
||
278 | cmp al,9 |
||
279 | ja bad_number |
||
280 | jmp dec_out_of_range |
||
281 | dec_out_of_range_finished: |
||
282 | or ebp,-1 |
||
283 | jmp number_ok |
||
284 | bad_number: |
||
285 | pop eax |
||
286 | invalid_number: |
||
287 | mov esi,[number_start] |
||
288 | dec esi |
||
289 | not_number: |
||
290 | dec esi |
||
291 | stc |
||
292 | ret |
||
293 | get_bin_number: |
||
294 | xor bl,bl |
||
295 | get_bin_digit: |
||
296 | cmp esi,[number_start] |
||
297 | jb number_ok |
||
298 | movzx eax,byte [esi] |
||
299 | cmp al,27h |
||
300 | je bin_digit_skip |
||
301 | sub al,30h |
||
302 | cmp al,1 |
||
303 | ja bad_number |
||
304 | xor edx,edx |
||
305 | mov cl,bl |
||
306 | dec esi |
||
307 | cmp bl,64 |
||
308 | je bin_out_of_range |
||
309 | inc bl |
||
310 | cmp cl,32 |
||
311 | jae bin_digit_high |
||
312 | shl eax,cl |
||
313 | or dword [edi],eax |
||
314 | jmp get_bin_digit |
||
315 | bin_digit_high: |
||
316 | sub cl,32 |
||
317 | shl eax,cl |
||
318 | or dword [edi+4],eax |
||
319 | jmp get_bin_digit |
||
320 | bin_out_of_range: |
||
321 | or al,al |
||
322 | jz get_bin_digit |
||
323 | or ebp,-1 |
||
324 | jmp get_bin_digit |
||
325 | bin_digit_skip: |
||
326 | dec esi |
||
327 | jmp get_bin_digit |
||
328 | pascal_hex_number: |
||
329 | cmp cl,1 |
||
330 | je bad_number |
||
331 | get_hex_number: |
||
332 | xor bl,bl |
||
333 | get_hex_digit: |
||
334 | cmp esi,[number_start] |
||
335 | jb number_ok |
||
336 | movzx eax,byte [esi] |
||
337 | cmp al,27h |
||
338 | je hex_digit_skip |
||
339 | cmp al,'x' |
||
340 | je hex_number_ok |
||
341 | cmp al,'$' |
||
342 | je pascal_hex_ok |
||
343 | sub al,30h |
||
344 | cmp al,9 |
||
345 | jbe hex_digit_ok |
||
346 | sub al,7 |
||
347 | cmp al,15 |
||
348 | jbe hex_letter_digit_ok |
||
349 | sub al,20h |
||
350 | cmp al,15 |
||
351 | ja bad_number |
||
352 | hex_letter_digit_ok: |
||
353 | cmp al,10 |
||
354 | jb bad_number |
||
355 | hex_digit_ok: |
||
356 | xor edx,edx |
||
357 | mov cl,bl |
||
358 | dec esi |
||
359 | cmp bl,64 |
||
360 | je hex_out_of_range |
||
361 | add bl,4 |
||
362 | cmp cl,32 |
||
363 | jae hex_digit_high |
||
364 | shl eax,cl |
||
365 | or dword [edi],eax |
||
366 | jmp get_hex_digit |
||
367 | hex_digit_high: |
||
368 | sub cl,32 |
||
369 | shl eax,cl |
||
370 | or dword [edi+4],eax |
||
371 | jmp get_hex_digit |
||
372 | hex_out_of_range: |
||
373 | or al,al |
||
374 | jz get_hex_digit |
||
375 | or ebp,-1 |
||
376 | jmp get_hex_digit |
||
377 | hex_digit_skip: |
||
378 | dec esi |
||
379 | jmp get_hex_digit |
||
380 | get_oct_number: |
||
381 | xor bl,bl |
||
382 | get_oct_digit: |
||
383 | cmp esi,[number_start] |
||
384 | jb number_ok |
||
385 | movzx eax,byte [esi] |
||
386 | cmp al,27h |
||
387 | je oct_digit_skip |
||
388 | sub al,30h |
||
389 | cmp al,7 |
||
390 | ja bad_number |
||
391 | oct_digit_ok: |
||
392 | xor edx,edx |
||
393 | mov cl,bl |
||
394 | dec esi |
||
395 | cmp bl,63 |
||
2664 | dunkaist | 396 | ja oct_out_of_range |
397 | jne oct_range_ok |
||
398 | cmp al,1 |
||
399 | ja oct_out_of_range |
||
400 | oct_range_ok: |
||
401 | add bl,3 |
||
2287 | heavyiron | 402 | cmp cl,30 |
403 | je oct_digit_wrap |
||
404 | ja oct_digit_high |
||
405 | shl eax,cl |
||
406 | or dword [edi],eax |
||
407 | jmp get_oct_digit |
||
408 | oct_digit_wrap: |
||
409 | shl eax,cl |
||
410 | adc dword [edi+4],0 |
||
411 | or dword [edi],eax |
||
412 | jmp get_oct_digit |
||
413 | oct_digit_high: |
||
414 | sub cl,32 |
||
415 | shl eax,cl |
||
416 | or dword [edi+4],eax |
||
417 | jmp get_oct_digit |
||
418 | oct_digit_skip: |
||
419 | dec esi |
||
420 | jmp get_oct_digit |
||
421 | oct_out_of_range: |
||
422 | or al,al |
||
423 | jz get_oct_digit |
||
424 | or ebp,-1 |
||
425 | jmp get_oct_digit |
||
426 | hex_number_ok: |
||
427 | dec esi |
||
428 | pascal_hex_ok: |
||
429 | cmp esi,[number_start] |
||
430 | jne bad_number |
||
431 | number_ok: |
||
432 | pop esi |
||
433 | number_done: |
||
434 | clc |
||
435 | ret |
||
436 | get_text_number: |
||
437 | lods dword [esi] |
||
438 | mov edx,eax |
||
439 | xor bl,bl |
||
440 | mov dword [edi],0 |
||
441 | mov dword [edi+4],0 |
||
442 | get_text_character: |
||
443 | sub edx,1 |
||
444 | jc number_done |
||
445 | movzx eax,byte [esi] |
||
446 | inc esi |
||
447 | mov cl,bl |
||
448 | cmp bl,64 |
||
449 | je text_out_of_range |
||
450 | add bl,8 |
||
451 | cmp cl,32 |
||
452 | jae text_character_high |
||
453 | shl eax,cl |
||
454 | or dword [edi],eax |
||
455 | jmp get_text_character |
||
456 | text_character_high: |
||
457 | sub cl,32 |
||
458 | shl eax,cl |
||
459 | or dword [edi+4],eax |
||
460 | jmp get_text_character |
||
461 | text_out_of_range: |
||
462 | or ebp,-1 |
||
463 | jmp get_text_character |
||
464 | |||
465 | |||
466 | push edi esi |
||
467 | lods byte [esi] |
||
468 | cmp al,1Ah |
||
469 | je fp_value_start |
||
470 | cmp al,'-' |
||
471 | je fp_sign_ok |
||
472 | cmp al,'+' |
||
473 | jne not_fp_value |
||
474 | fp_sign_ok: |
||
475 | lods byte [esi] |
||
476 | cmp al,1Ah |
||
477 | jne not_fp_value |
||
478 | fp_value_start: |
||
479 | lods byte [esi] |
||
480 | movzx ecx,al |
||
481 | cmp cl,1 |
||
482 | jbe not_fp_value |
||
483 | lea edx,[esi+1] |
||
484 | xor ah,ah |
||
485 | check_fp_value: |
||
486 | lods byte [esi] |
||
487 | cmp al,'.' |
||
488 | je fp_character_dot |
||
489 | cmp al,'E' |
||
490 | je fp_character_exp |
||
491 | cmp al,'e' |
||
492 | je fp_character_exp |
||
493 | cmp al,'F' |
||
494 | je fp_last_character |
||
495 | cmp al,'f' |
||
496 | je fp_last_character |
||
497 | digit_expected: |
||
498 | cmp al,'0' |
||
499 | jb not_fp_value |
||
500 | cmp al,'9' |
||
501 | ja not_fp_value |
||
502 | jmp fp_character_ok |
||
503 | fp_character_dot: |
||
504 | cmp esi,edx |
||
505 | je not_fp_value |
||
506 | or ah,ah |
||
507 | jnz not_fp_value |
||
508 | or ah,1 |
||
509 | lods byte [esi] |
||
510 | loop digit_expected |
||
511 | not_fp_value: |
||
512 | pop esi edi |
||
513 | stc |
||
514 | ret |
||
515 | fp_last_character: |
||
516 | cmp cl,1 |
||
517 | jne not_fp_value |
||
518 | or ah,4 |
||
519 | jmp fp_character_ok |
||
520 | fp_character_exp: |
||
521 | cmp esi,edx |
||
522 | je not_fp_value |
||
523 | cmp ah,1 |
||
524 | ja not_fp_value |
||
525 | or ah,2 |
||
526 | cmp ecx,1 |
||
527 | jne fp_character_ok |
||
528 | cmp byte [esi],'+' |
||
529 | je fp_exp_sign |
||
530 | cmp byte [esi],'-' |
||
531 | jne fp_character_ok |
||
532 | fp_exp_sign: |
||
533 | inc esi |
||
534 | cmp byte [esi],1Ah |
||
535 | jne not_fp_value |
||
536 | inc esi |
||
537 | lods byte [esi] |
||
538 | movzx ecx,al |
||
539 | inc ecx |
||
540 | fp_character_ok: |
||
541 | dec ecx |
||
542 | jnz check_fp_value |
||
543 | or ah,ah |
||
544 | jz not_fp_value |
||
545 | pop esi |
||
546 | lods byte [esi] |
||
547 | mov [fp_sign],0 |
||
548 | cmp al,1Ah |
||
549 | je fp_get |
||
550 | inc esi |
||
551 | cmp al,'+' |
||
552 | je fp_get |
||
553 | mov [fp_sign],1 |
||
554 | fp_get: |
||
555 | lods byte [esi] |
||
556 | movzx ecx,al |
||
557 | xor edx,edx |
||
558 | mov edi,fp_value |
||
559 | mov [edi],edx |
||
560 | mov [edi+4],edx |
||
561 | mov [edi+12],edx |
||
562 | call fp_optimize |
||
563 | mov [fp_format],0 |
||
564 | mov al,[esi] |
||
565 | fp_before_dot: |
||
566 | lods byte [esi] |
||
567 | cmp al,'.' |
||
568 | je fp_dot |
||
569 | cmp al,'E' |
||
570 | je fp_exponent |
||
571 | cmp al,'e' |
||
572 | je fp_exponent |
||
573 | cmp al,'F' |
||
574 | je fp_done |
||
575 | cmp al,'f' |
||
576 | je fp_done |
||
577 | sub al,30h |
||
578 | mov edi,fp_value+16 |
||
579 | xor edx,edx |
||
580 | mov dword [edi+12],edx |
||
581 | mov dword [edi],edx |
||
582 | mov dword [edi+4],edx |
||
583 | mov [edi+7],al |
||
584 | mov dl,7 |
||
585 | mov dword [edi+8],edx |
||
586 | call fp_optimize |
||
587 | mov edi,fp_value |
||
588 | push ecx |
||
589 | mov ecx,10 |
||
590 | call fp_mul |
||
591 | pop ecx |
||
592 | mov ebx,fp_value+16 |
||
593 | call fp_add |
||
594 | loop fp_before_dot |
||
595 | fp_dot: |
||
596 | mov edi,fp_value+16 |
||
597 | xor edx,edx |
||
598 | mov [edi],edx |
||
599 | mov [edi+4],edx |
||
600 | mov byte [edi+7],80h |
||
601 | mov [edi+8],edx |
||
602 | mov dword [edi+12],edx |
||
603 | dec ecx |
||
604 | jz fp_done |
||
605 | fp_after_dot: |
||
606 | lods byte [esi] |
||
607 | cmp al,'E' |
||
608 | je fp_exponent |
||
609 | cmp al,'e' |
||
610 | je fp_exponent |
||
611 | cmp al,'F' |
||
612 | je fp_done |
||
613 | cmp al,'f' |
||
614 | je fp_done |
||
615 | inc [fp_format] |
||
616 | cmp [fp_format],80h |
||
617 | jne fp_counter_ok |
||
618 | mov [fp_format],7Fh |
||
619 | fp_counter_ok: |
||
620 | dec esi |
||
621 | mov edi,fp_value+16 |
||
622 | push ecx |
||
623 | mov ecx,10 |
||
624 | call fp_div |
||
625 | push dword [edi] |
||
626 | push dword [edi+4] |
||
627 | push dword [edi+8] |
||
628 | push dword [edi+12] |
||
629 | lods byte [esi] |
||
630 | sub al,30h |
||
631 | movzx ecx,al |
||
632 | call fp_mul |
||
633 | mov ebx,edi |
||
634 | mov edi,fp_value |
||
635 | call fp_add |
||
636 | mov edi,fp_value+16 |
||
637 | pop dword [edi+12] |
||
638 | pop dword [edi+8] |
||
639 | pop dword [edi+4] |
||
640 | pop dword [edi] |
||
641 | pop ecx |
||
642 | dec ecx |
||
643 | jnz fp_after_dot |
||
644 | jmp fp_done |
||
645 | fp_exponent: |
||
646 | or [fp_format],80h |
||
647 | xor edx,edx |
||
648 | xor ebp,ebp |
||
649 | dec ecx |
||
650 | jnz get_exponent |
||
651 | cmp byte [esi],'+' |
||
652 | je fp_exponent_sign |
||
653 | cmp byte [esi],'-' |
||
654 | jne fp_done |
||
655 | not ebp |
||
656 | fp_exponent_sign: |
||
657 | add esi,2 |
||
658 | lods byte [esi] |
||
659 | movzx ecx,al |
||
660 | get_exponent: |
||
661 | movzx eax,byte [esi] |
||
662 | inc esi |
||
663 | sub al,30h |
||
664 | cmp al,10 |
||
665 | jae exponent_ok |
||
666 | imul edx,10 |
||
667 | cmp edx,8000h |
||
668 | jae value_out_of_range |
||
669 | add edx,eax |
||
670 | loop get_exponent |
||
671 | exponent_ok: |
||
672 | mov edi,fp_value |
||
673 | or edx,edx |
||
674 | jz fp_done |
||
675 | mov ecx,edx |
||
676 | or ebp,ebp |
||
677 | jnz fp_negative_power |
||
678 | fp_power: |
||
679 | push ecx |
||
680 | mov ecx,10 |
||
681 | call fp_mul |
||
682 | pop ecx |
||
683 | loop fp_power |
||
684 | jmp fp_done |
||
685 | fp_negative_power: |
||
686 | push ecx |
||
687 | mov ecx,10 |
||
688 | call fp_div |
||
689 | pop ecx |
||
690 | loop fp_negative_power |
||
691 | fp_done: |
||
692 | mov edi,fp_value |
||
693 | mov al,[fp_format] |
||
694 | mov [edi+10],al |
||
695 | mov al,[fp_sign] |
||
696 | mov [edi+11],al |
||
697 | test byte [edi+15],80h |
||
698 | jz fp_ok |
||
699 | add dword [edi],1 |
||
700 | adc dword [edi+4],0 |
||
701 | jnc fp_ok |
||
702 | mov eax,[edi+4] |
||
703 | shrd [edi],eax,1 |
||
704 | shr eax,1 |
||
705 | or eax,80000000h |
||
706 | mov [edi+4],eax |
||
707 | inc word [edi+8] |
||
708 | fp_ok: |
||
709 | pop edi |
||
710 | clc |
||
711 | ret |
||
712 | fp_mul: |
||
713 | or ecx,ecx |
||
714 | jz fp_zero |
||
715 | mov eax,[edi+12] |
||
716 | mul ecx |
||
717 | mov [edi+12],eax |
||
718 | mov ebx,edx |
||
719 | mov eax,[edi] |
||
720 | mul ecx |
||
721 | add eax,ebx |
||
722 | adc edx,0 |
||
723 | mov [edi],eax |
||
724 | mov ebx,edx |
||
725 | mov eax,[edi+4] |
||
726 | mul ecx |
||
727 | add eax,ebx |
||
728 | adc edx,0 |
||
729 | mov [edi+4],eax |
||
730 | .loop: |
||
731 | or edx,edx |
||
732 | jz .done |
||
733 | mov eax,[edi] |
||
734 | shrd [edi+12],eax,1 |
||
735 | mov eax,[edi+4] |
||
736 | shrd [edi],eax,1 |
||
737 | shrd eax,edx,1 |
||
738 | mov [edi+4],eax |
||
739 | shr edx,1 |
||
740 | inc dword [edi+8] |
||
741 | cmp dword [edi+8],8000h |
||
742 | jge value_out_of_range |
||
743 | jmp .loop |
||
744 | .done: |
||
745 | ret |
||
746 | fp_div: |
||
747 | mov eax,[edi+4] |
||
748 | xor edx,edx |
||
749 | div ecx |
||
750 | mov [edi+4],eax |
||
751 | mov eax,[edi] |
||
752 | div ecx |
||
753 | mov [edi],eax |
||
754 | mov eax,[edi+12] |
||
755 | div ecx |
||
756 | mov [edi+12],eax |
||
757 | mov ebx,eax |
||
758 | or ebx,[edi] |
||
759 | or ebx,[edi+4] |
||
760 | jz fp_zero |
||
761 | .loop: |
||
762 | test byte [edi+7],80h |
||
763 | jnz .exp_ok |
||
764 | mov eax,[edi] |
||
765 | shld [edi+4],eax,1 |
||
766 | mov eax,[edi+12] |
||
767 | shld [edi],eax,1 |
||
768 | add eax,eax |
||
769 | mov [edi+12],eax |
||
770 | dec dword [edi+8] |
||
771 | add edx,edx |
||
772 | jmp .loop |
||
773 | .exp_ok: |
||
774 | mov eax,edx |
||
775 | xor edx,edx |
||
776 | div ecx |
||
777 | add [edi+12],eax |
||
778 | adc dword [edi],0 |
||
779 | adc dword [edi+4],0 |
||
780 | jnc .done |
||
781 | mov eax,[edi+4] |
||
782 | mov ebx,[edi] |
||
783 | shrd [edi],eax,1 |
||
784 | shrd [edi+12],ebx,1 |
||
785 | shr eax,1 |
||
786 | or eax,80000000h |
||
787 | mov [edi+4],eax |
||
788 | inc dword [edi+8] |
||
789 | .done: |
||
790 | ret |
||
791 | fp_add: |
||
792 | cmp dword [ebx+8],8000h |
||
793 | je .done |
||
794 | cmp dword [edi+8],8000h |
||
795 | je .copy |
||
796 | mov eax,[ebx+8] |
||
797 | cmp eax,[edi+8] |
||
798 | jge .exp_ok |
||
799 | mov eax,[edi+8] |
||
800 | .exp_ok: |
||
801 | call .change_exp |
||
802 | xchg ebx,edi |
||
803 | call .change_exp |
||
804 | xchg ebx,edi |
||
805 | mov edx,[ebx+12] |
||
806 | mov eax,[ebx] |
||
807 | mov ebx,[ebx+4] |
||
808 | add [edi+12],edx |
||
809 | adc [edi],eax |
||
810 | adc [edi+4],ebx |
||
811 | jnc .done |
||
812 | mov eax,[edi] |
||
813 | shrd [edi+12],eax,1 |
||
814 | mov eax,[edi+4] |
||
815 | shrd [edi],eax,1 |
||
816 | shr eax,1 |
||
817 | or eax,80000000h |
||
818 | mov [edi+4],eax |
||
819 | inc dword [edi+8] |
||
820 | .done: |
||
821 | ret |
||
822 | .copy: |
||
823 | mov eax,[ebx] |
||
824 | mov [edi],eax |
||
825 | mov eax,[ebx+4] |
||
826 | mov [edi+4],eax |
||
827 | mov eax,[ebx+8] |
||
828 | mov [edi+8],eax |
||
829 | mov eax,[ebx+12] |
||
830 | mov [edi+12],eax |
||
831 | ret |
||
832 | .change_exp: |
||
833 | push ecx |
||
834 | mov ecx,eax |
||
835 | sub ecx,[ebx+8] |
||
836 | mov edx,[ebx+4] |
||
837 | jecxz .exp_done |
||
838 | .exp_loop: |
||
839 | mov ebp,[ebx] |
||
840 | shrd [ebx+12],ebp,1 |
||
841 | shrd [ebx],edx,1 |
||
842 | shr edx,1 |
||
843 | inc dword [ebx+8] |
||
844 | loop .exp_loop |
||
845 | .exp_done: |
||
846 | mov [ebx+4],edx |
||
847 | pop ecx |
||
848 | ret |
||
849 | fp_optimize: |
||
850 | mov eax,[edi] |
||
851 | mov ebp,[edi+4] |
||
852 | or ebp,[edi] |
||
853 | or ebp,[edi+12] |
||
854 | jz fp_zero |
||
855 | .loop: |
||
856 | test byte [edi+7],80h |
||
857 | jnz .done |
||
858 | shld [edi+4],eax,1 |
||
859 | mov ebp,[edi+12] |
||
860 | shld eax,ebp,1 |
||
861 | mov [edi],eax |
||
862 | shl dword [edi+12],1 |
||
863 | dec dword [edi+8] |
||
864 | jmp .loop |
||
865 | .done: |
||
866 | ret |
||
867 | fp_zero: |
||
868 | mov dword [edi+8],8000h |
||
869 | ret |
||
870 | |||
871 | |||
872 | xor al,al |
||
873 | preevaluate_embedded_logical_expression: |
||
874 | mov [logical_value_wrapping],al |
||
875 | push edi |
||
876 | call preevaluate_logical_value |
||
877 | preevaluation_loop: |
||
878 | cmp al,0FFh |
||
879 | je invalid_logical_expression |
||
880 | mov dl,[esi] |
||
881 | inc esi |
||
882 | cmp dl,'|' |
||
883 | je preevaluate_or |
||
884 | cmp dl,'&' |
||
885 | je preevaluate_and |
||
886 | cmp dl,'}' |
||
887 | je preevaluation_done |
||
888 | or dl,dl |
||
889 | jnz invalid_logical_expression |
||
890 | preevaluation_done: |
||
891 | pop edx |
||
892 | dec esi |
||
893 | ret |
||
894 | preevaluate_or: |
||
895 | cmp al,'1' |
||
896 | je quick_true |
||
897 | cmp al,'0' |
||
898 | je leave_only_following |
||
899 | push edi |
||
900 | mov al,dl |
||
901 | stos byte [edi] |
||
902 | call preevaluate_logical_value |
||
903 | pop ebx |
||
904 | cmp al,'0' |
||
905 | je leave_only_preceding |
||
906 | cmp al,'1' |
||
907 | jne preevaluation_loop |
||
908 | stos byte [edi] |
||
909 | xor al,al |
||
910 | jmp preevaluation_loop |
||
911 | preevaluate_and: |
||
912 | cmp al,'0' |
||
913 | je quick_false |
||
914 | cmp al,'1' |
||
915 | je leave_only_following |
||
916 | push edi |
||
917 | mov al,dl |
||
918 | stos byte [edi] |
||
919 | call preevaluate_logical_value |
||
920 | pop ebx |
||
921 | cmp al,'1' |
||
922 | je leave_only_preceding |
||
923 | cmp al,'0' |
||
924 | jne preevaluation_loop |
||
925 | stos byte [edi] |
||
926 | xor al,al |
||
927 | jmp preevaluation_loop |
||
928 | leave_only_following: |
||
929 | mov edi,[esp] |
||
930 | call preevaluate_logical_value |
||
931 | jmp preevaluation_loop |
||
932 | leave_only_preceding: |
||
933 | mov edi,ebx |
||
934 | xor al,al |
||
935 | jmp preevaluation_loop |
||
936 | quick_true: |
||
937 | call skip_logical_value |
||
938 | jc invalid_logical_expression |
||
939 | mov edi,[esp] |
||
940 | mov al,'1' |
||
941 | jmp preevaluation_loop |
||
942 | quick_false: |
||
943 | call skip_logical_value |
||
944 | jc invalid_logical_expression |
||
945 | mov edi,[esp] |
||
946 | mov al,'0' |
||
947 | jmp preevaluation_loop |
||
948 | invalid_logical_expression: |
||
949 | pop edi |
||
950 | mov esi,edi |
||
951 | mov al,0FFh |
||
952 | stos byte [edi] |
||
953 | ret |
||
954 | skip_logical_value: |
||
955 | cmp byte [esi],'~' |
||
956 | jne negation_skipped |
||
957 | inc esi |
||
958 | jmp skip_logical_value |
||
959 | negation_skipped: |
||
960 | mov al,[esi] |
||
961 | cmp al,'{' |
||
962 | jne skip_simple_logical_value |
||
963 | inc esi |
||
964 | xchg al,[logical_value_wrapping] |
||
965 | push eax |
||
966 | skip_logical_expression: |
||
967 | call skip_logical_value |
||
968 | lods byte [esi] |
||
969 | or al,al |
||
970 | jz wrongly_structured_logical_expression |
||
971 | cmp al,0Fh |
||
972 | je wrongly_structured_logical_expression |
||
973 | cmp al,'|' |
||
974 | je skip_logical_expression |
||
975 | cmp al,'&' |
||
976 | je skip_logical_expression |
||
977 | cmp al,'}' |
||
978 | jne wrongly_structured_logical_expression |
||
979 | pop eax |
||
980 | mov [logical_value_wrapping],al |
||
981 | logical_value_skipped: |
||
982 | clc |
||
983 | ret |
||
984 | wrongly_structured_logical_expression: |
||
985 | pop eax |
||
986 | stc |
||
987 | ret |
||
988 | skip_simple_logical_value: |
||
989 | mov [logical_value_parentheses],0 |
||
990 | find_simple_logical_value_end: |
||
991 | mov al,[esi] |
||
992 | or al,al |
||
993 | jz logical_value_skipped |
||
994 | cmp al,0Fh |
||
995 | je logical_value_skipped |
||
996 | cmp al,'|' |
||
997 | je logical_value_skipped |
||
998 | cmp al,'&' |
||
999 | je logical_value_skipped |
||
1000 | cmp al,'{' |
||
1001 | je skip_logical_value_internal_parenthesis |
||
1002 | cmp al,'}' |
||
1003 | jne skip_logical_value_symbol |
||
1004 | sub [logical_value_parentheses],1 |
||
1005 | jnc skip_logical_value_symbol |
||
1006 | cmp [logical_value_wrapping],'{' |
||
1007 | jne skip_logical_value_symbol |
||
1008 | jmp logical_value_skipped |
||
1009 | skip_logical_value_internal_parenthesis: |
||
1010 | inc [logical_value_parentheses] |
||
1011 | skip_logical_value_symbol: |
||
1012 | call skip_symbol |
||
1013 | jmp find_simple_logical_value_end |
||
1014 | preevaluate_logical_value: |
||
1015 | mov ebp,edi |
||
1016 | preevaluate_negation: |
||
1017 | cmp byte [esi],'~' |
||
1018 | jne preevaluate_negation_ok |
||
1019 | movs byte [edi],[esi] |
||
1020 | jmp preevaluate_negation |
||
1021 | preevaluate_negation_ok: |
||
1022 | mov ebx,esi |
||
1023 | cmp byte [esi],'{' |
||
1024 | jne preevaluate_simple_logical_value |
||
1025 | lods byte [esi] |
||
1026 | stos byte [edi] |
||
1027 | push ebp |
||
1028 | mov dl,[logical_value_wrapping] |
||
1029 | push edx |
||
1030 | call preevaluate_embedded_logical_expression |
||
1031 | pop edx |
||
1032 | mov [logical_value_wrapping],dl |
||
1033 | pop ebp |
||
1034 | cmp al,0FFh |
||
1035 | je invalid_logical_value |
||
1036 | cmp byte [esi],'}' |
||
1037 | jne invalid_logical_value |
||
1038 | or al,al |
||
1039 | jnz preevaluated_expression_value |
||
1040 | movs byte [edi],[esi] |
||
1041 | ret |
||
1042 | preevaluated_expression_value: |
||
1043 | inc esi |
||
1044 | lea edx,[edi-1] |
||
1045 | sub edx,ebp |
||
1046 | test edx,1 |
||
1047 | jz expression_negation_ok |
||
1048 | xor al,1 |
||
1049 | expression_negation_ok: |
||
1050 | mov edi,ebp |
||
1051 | ret |
||
1052 | invalid_logical_value: |
||
1053 | mov edi,ebp |
||
1054 | mov al,0FFh |
||
1055 | ret |
||
1056 | preevaluate_simple_logical_value: |
||
1057 | xor edx,edx |
||
1058 | mov [logical_value_parentheses],edx |
||
1059 | find_logical_value_boundaries: |
||
1060 | mov al,[esi] |
||
1061 | or al,al |
||
1062 | jz logical_value_boundaries_found |
||
1063 | cmp al,'{' |
||
1064 | je logical_value_internal_parentheses |
||
1065 | cmp al,'}' |
||
1066 | je logical_value_boundaries_parenthesis_close |
||
1067 | cmp al,'|' |
||
1068 | je logical_value_boundaries_found |
||
1069 | cmp al,'&' |
||
1070 | je logical_value_boundaries_found |
||
1071 | or edx,edx |
||
1072 | jnz next_symbol_in_logical_value |
||
1073 | cmp al,0F0h |
||
1074 | je preevaluable_logical_operator |
||
1075 | cmp al,0F7h |
||
1076 | je preevaluable_logical_operator |
||
1077 | cmp al,0F6h |
||
1078 | jne next_symbol_in_logical_value |
||
1079 | preevaluable_logical_operator: |
||
1080 | mov edx,esi |
||
1081 | next_symbol_in_logical_value: |
||
1082 | call skip_symbol |
||
1083 | jmp find_logical_value_boundaries |
||
1084 | logical_value_internal_parentheses: |
||
1085 | inc [logical_value_parentheses] |
||
1086 | jmp next_symbol_in_logical_value |
||
1087 | logical_value_boundaries_parenthesis_close: |
||
1088 | sub [logical_value_parentheses],1 |
||
1089 | jnc next_symbol_in_logical_value |
||
1090 | cmp [logical_value_wrapping],'{' |
||
1091 | jne next_symbol_in_logical_value |
||
1092 | logical_value_boundaries_found: |
||
1093 | or edx,edx |
||
1094 | jz non_preevaluable_logical_value |
||
1095 | mov al,[edx] |
||
1096 | cmp al,0F0h |
||
1097 | je compare_symbols |
||
1098 | cmp al,0F7h |
||
1099 | je compare_symbol_types |
||
1100 | cmp al,0F6h |
||
1101 | je scan_symbols_list |
||
1102 | non_preevaluable_logical_value: |
||
1103 | mov ecx,esi |
||
1104 | mov esi,ebx |
||
1105 | sub ecx,esi |
||
1106 | jz invalid_logical_value |
||
1107 | cmp esi,edi |
||
1108 | je leave_logical_value_intact |
||
1109 | rep movs byte [edi],[esi] |
||
1110 | xor al,al |
||
1111 | ret |
||
1112 | leave_logical_value_intact: |
||
1113 | add edi,ecx |
||
1114 | add esi,ecx |
||
1115 | xor al,al |
||
1116 | ret |
||
1117 | compare_symbols: |
||
1118 | lea ecx,[esi-1] |
||
1119 | sub ecx,edx |
||
1120 | mov eax,edx |
||
1121 | sub eax,ebx |
||
1122 | cmp ecx,eax |
||
1123 | jne preevaluated_false |
||
1124 | push esi edi |
||
1125 | mov esi,ebx |
||
1126 | lea edi,[edx+1] |
||
1127 | repe cmps byte [esi],[edi] |
||
1128 | pop edi esi |
||
1129 | je preevaluated_true |
||
1130 | preevaluated_false: |
||
1131 | mov eax,edi |
||
1132 | sub eax,ebp |
||
1133 | test eax,1 |
||
1134 | jnz store_true |
||
1135 | store_false: |
||
1136 | mov edi,ebp |
||
1137 | mov al,'0' |
||
1138 | ret |
||
1139 | preevaluated_true: |
||
1140 | mov eax,edi |
||
1141 | sub eax,ebp |
||
1142 | test eax,1 |
||
1143 | jnz store_false |
||
1144 | store_true: |
||
1145 | mov edi,ebp |
||
1146 | mov al,'1' |
||
1147 | ret |
||
1148 | compare_symbol_types: |
||
1149 | push esi |
||
1150 | lea esi,[edx+1] |
||
1151 | type_comparison: |
||
1152 | cmp esi,[esp] |
||
1153 | je types_compared |
||
1154 | mov al,[esi] |
||
1155 | cmp al,[ebx] |
||
1156 | jne different_type |
||
1157 | cmp al,'(' |
||
1158 | jne equal_type |
||
1159 | mov al,[esi+1] |
||
1160 | mov ah,[ebx+1] |
||
1161 | cmp al,ah |
||
1162 | je equal_type |
||
1163 | or al,al |
||
1164 | jz different_type |
||
1165 | or ah,ah |
||
1166 | jz different_type |
||
1167 | cmp al,'.' |
||
1168 | je different_type |
||
1169 | cmp ah,'.' |
||
1170 | je different_type |
||
1171 | equal_type: |
||
1172 | call skip_symbol |
||
1173 | xchg esi,ebx |
||
1174 | call skip_symbol |
||
1175 | xchg esi,ebx |
||
1176 | jmp type_comparison |
||
1177 | types_compared: |
||
1178 | pop esi |
||
1179 | cmp byte [ebx],0F7h |
||
1180 | jne preevaluated_false |
||
1181 | jmp preevaluated_true |
||
1182 | different_type: |
||
1183 | pop esi |
||
1184 | jmp preevaluated_false |
||
1185 | scan_symbols_list: |
||
1186 | push edi esi |
||
1187 | lea esi,[edx+1] |
||
1188 | sub edx,ebx |
||
1189 | lods byte [esi] |
||
1190 | cmp al,'<' |
||
1191 | jne invalid_symbols_list |
||
1192 | get_next_from_list: |
||
1193 | mov edi,esi |
||
1194 | get_from_list: |
||
1195 | cmp byte [esi],',' |
||
1196 | je compare_in_list |
||
1197 | cmp byte [esi],'>' |
||
1198 | je compare_in_list |
||
1199 | cmp esi,[esp] |
||
1200 | jae invalid_symbols_list |
||
1201 | call skip_symbol |
||
1202 | jmp get_from_list |
||
1203 | compare_in_list: |
||
1204 | mov ecx,esi |
||
1205 | sub ecx,edi |
||
1206 | cmp ecx,edx |
||
1207 | jne not_equal_length_in_list |
||
1208 | mov esi,ebx |
||
1209 | repe cmps byte [esi],[edi] |
||
1210 | mov esi,edi |
||
1211 | jne not_equal_in_list |
||
1212 | skip_rest_of_list: |
||
1213 | cmp byte [esi],'>' |
||
1214 | je check_list_end |
||
1215 | cmp esi,[esp] |
||
1216 | jae invalid_symbols_list |
||
1217 | call skip_symbol |
||
1218 | jmp skip_rest_of_list |
||
1219 | check_list_end: |
||
1220 | inc esi |
||
1221 | cmp esi,[esp] |
||
1222 | jne invalid_symbols_list |
||
1223 | pop esi edi |
||
1224 | jmp preevaluated_true |
||
1225 | not_equal_in_list: |
||
1226 | add esi,ecx |
||
1227 | not_equal_length_in_list: |
||
1228 | lods byte [esi] |
||
1229 | cmp al,',' |
||
1230 | je get_next_from_list |
||
1231 | cmp esi,[esp] |
||
1232 | jne invalid_symbols_list |
||
1233 | pop esi edi |
||
1234 | jmp preevaluated_false |
||
1235 | invalid_symbols_list: |
||
1236 | pop esi edi |
||
1237 | jmp invalid_logical_value' |
||
1238 | > |