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