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