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