Subversion Repositories Kolibri OS

Rev

Rev 31 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
 
2
; Copyright (c) 1999-2006, Tomasz Grysztar.
109 heavyiron 3
; All rights reserved.
31 halyavin 4
5
 
6
        push    ebp
109 heavyiron 7
        call    get_fp_value
8
        jnc     fp_expression
9
        mov     [current_offset],esp
10
      expression_loop:
31 halyavin 11
        push    edi
109 heavyiron 12
        mov     edi,single_operand_operators
13
        call    get_operator
14
        pop     edi
15
        or      al,al
16
        jz      expression_element
17
        push    eax
18
        jmp     expression_loop
19
      expression_element:
20
        mov     al,[esi]
21
        cmp     al,1Ah
22
        je      expression_number
23
        cmp     al,22h
24
        je      expression_number
25
        cmp     al,'('
26
        je      expression_number
27
        mov     al,'!'
28
        stos    byte [edi]
29
        jmp     expression_operator
30
      expression_number:
31 halyavin 31
        call    convert_number
109 heavyiron 32
      expression_operator:
31 halyavin 33
        push    edi
109 heavyiron 34
        mov     edi,operators
35
        call    get_operator
36
        pop     edi
37
        or      al,al
38
        jz      expression_end
39
      operators_loop:
31 halyavin 40
        cmp     esp,[current_offset]
109 heavyiron 41
        je      push_operator
42
        mov     bl,al
43
        and     bl,0F0h
44
        mov     bh,byte [esp]
45
        and     bh,0F0h
46
        cmp     bl,bh
47
        ja      push_operator
48
        pop     ebx
49
        mov     byte [edi],bl
50
        inc     edi
51
        jmp     operators_loop
52
      push_operator:
31 halyavin 53
        push    eax
109 heavyiron 54
        jmp     expression_loop
55
      expression_end:
31 halyavin 56
        cmp     esp,[current_offset]
109 heavyiron 57
        je      expression_converted
58
        pop     eax
59
        stos    byte [edi]
60
        jmp     expression_end
61
      expression_converted:
31 halyavin 62
        pop     ebp
109 heavyiron 63
        ret
64
      fp_expression:
31 halyavin 65
        mov     al,'.'
109 heavyiron 66
        stos    byte [edi]
67
        mov     eax,[fp_value]
68
        stos    dword [edi]
69
        mov     eax,[fp_value+4]
70
        stos    dword [edi]
71
        mov     eax,[fp_value+8]
72
        stos    dword [edi]
73
        pop     ebp
74
        ret
75
31 halyavin 76
 
77
        lea     eax,[edi-10h]
109 heavyiron 78
        cmp     eax,[labels_list]
79
        jae     out_of_memory
80
        cmp     byte [esi],'('
81
        je      expression_value
82
        inc     edi
83
        call    get_number
84
        jc      symbol_value
85
        or      ebp,ebp
86
        jz      valid_number
87
        mov     byte [edi-1],0Fh
88
        ret
89
      valid_number:
31 halyavin 90
        cmp     dword [edi+4],0
109 heavyiron 91
        jne     qword_number
92
        cmp     word [edi+2],0
93
        jne     dword_number
94
        cmp     byte [edi+1],0
95
        jne     word_number
96
      byte_number:
31 halyavin 97
        mov     byte [edi-1],1
109 heavyiron 98
        inc     edi
99
        ret
100
      qword_number:
31 halyavin 101
        mov     byte [edi-1],8
109 heavyiron 102
        add     edi,8
103
        ret
104
      dword_number:
31 halyavin 105
        mov     byte [edi-1],4
109 heavyiron 106
        scas    dword [edi]
107
        ret
108
      word_number:
31 halyavin 109
        mov     byte [edi-1],2
109 heavyiron 110
        scas    word [edi]
111
        ret
112
      expression_value:
31 halyavin 113
        mov     eax,esp
109 heavyiron 114
        sub     eax,100h
115
        jc      stack_overflow
116
        cmp     eax,[stack_limit]
117
        jb      stack_overflow
118
        inc     esi
119
        push    [current_offset]
120
        call    convert_expression
121
        pop     [current_offset]
122
        lods    byte [esi]
123
        cmp     al,')'
124
        jne     invalid_expression
125
        ret
126
      symbol_value:
31 halyavin 127
        push    edi
109 heavyiron 128
        mov     edi,address_registers
129
        call    get_operator
130
        or      al,al
131
        jnz     register_value
132
        mov     edi,directive_operators
133
        call    get_operator
134
        pop     edi
135
        or      al,al
136
        jnz     broken_value
137
        lods    byte [esi]
138
        cmp     al,1Ah
139
        jne     invalid_value
140
        lods    byte [esi]
141
        movzx   ecx,al
142
        call    get_label_id
143
      store_label_value:
31 halyavin 144
        mov     byte [edi-1],11h
109 heavyiron 145
        stos    dword [edi]
146
        ret
147
      broken_value:
31 halyavin 148
        mov     eax,0Fh
109 heavyiron 149
        jmp     store_label_value
150
      register_value:
31 halyavin 151
        pop     edi
109 heavyiron 152
        mov     byte [edi-1],10h
153
        stos    byte [edi]
154
        ret
155
31 halyavin 156
 
157
        xor     ebp,ebp
109 heavyiron 158
        lods    byte [esi]
159
        cmp     al,22h
160
        je      get_text_number
161
        cmp     al,1Ah
162
        jne     not_number
163
        lods    byte [esi]
164
        movzx   ecx,al
165
        mov     [number_start],esi
166
        mov     al,[esi]
167
        cmp     al,'$'
168
        je      number_begin
169
        sub     al,30h
170
        cmp     al,9
171
        ja      invalid_number
172
      number_begin:
31 halyavin 173
        mov     ebx,esi
109 heavyiron 174
        add     esi,ecx
175
        push    esi
176
        dec     esi
177
        mov     dword [edi],0
178
        mov     dword [edi+4],0
179
        cmp     byte [ebx],'$'
180
        je      pascal_hex_number
181
        cmp     word [ebx],'0x'
182
        je      get_hex_number
183
        mov     al,[esi]
184
        dec     esi
185
        cmp     al,'h'
186
        je      get_hex_number
187
        cmp     al,'b'
188
        je      get_bin_number
189
        cmp     al,'d'
190
        je      get_dec_number
191
        cmp     al,'o'
192
        je      get_oct_number
193
        cmp     al,'H'
194
        je      get_hex_number
195
        cmp     al,'B'
196
        je      get_bin_number
197
        cmp     al,'D'
198
        je      get_dec_number
199
        cmp     al,'O'
200
        je      get_oct_number
201
        inc     esi
202
      get_dec_number:
31 halyavin 203
        mov     ebx,esi
109 heavyiron 204
        mov     esi,[number_start]
205
      get_dec_digit:
31 halyavin 206
        cmp     esi,ebx
109 heavyiron 207
        ja      number_ok
208
        xor     edx,edx
209
        mov     eax,[edi]
210
        shld    edx,eax,2
211
        shl     eax,2
212
        add     eax,[edi]
213
        adc     edx,0
214
        add     eax,eax
215
        adc     edx,edx
216
        mov     [edi],eax
217
        mov     eax,[edi+4]
218
        add     eax,eax
219
        jc      dec_out_of_range
220
        add     eax,eax
221
        jc      dec_out_of_range
222
        add     eax,[edi+4]
223
        jc      dec_out_of_range
224
        add     eax,eax
225
        jc      dec_out_of_range
226
        add     eax,edx
227
        jc      dec_out_of_range
228
        mov     [edi+4],eax
229
        movzx   eax,byte [esi]
230
        sub     al,30h
231
        cmp     al,9
232
        ja      bad_number
233
        add     [edi],eax
234
        adc     dword [edi+4],0
235
        jc      dec_out_of_range
236
        inc     esi
237
        jmp     get_dec_digit
238
      dec_out_of_range:
31 halyavin 239
        or      ebp,-1
109 heavyiron 240
        inc     esi
241
        jmp     get_dec_digit
242
      bad_number:
31 halyavin 243
        pop     eax
109 heavyiron 244
      invalid_number:
31 halyavin 245
        mov     esi,[number_start]
109 heavyiron 246
        dec     esi
247
      not_number:
31 halyavin 248
        dec     esi
109 heavyiron 249
        stc
250
        ret
251
      get_bin_number:
31 halyavin 252
        xor     bl,bl
109 heavyiron 253
      get_bin_digit:
31 halyavin 254
        cmp     esi,[number_start]
109 heavyiron 255
        jb      number_ok
256
        movzx   eax,byte [esi]
257
        sub     al,30h
258
        cmp     al,1
259
        ja      bad_number
260
        xor     edx,edx
261
        mov     cl,bl
262
        dec     esi
263
        cmp     bl,64
264
        je      bin_out_of_range
265
        inc     bl
266
        cmp     cl,32
267
        jae     bin_digit_high
268
        shl     eax,cl
269
        or      dword [edi],eax
270
        jmp     get_bin_digit
271
      bin_digit_high:
31 halyavin 272
        sub     cl,32
109 heavyiron 273
        shl     eax,cl
274
        or      dword [edi+4],eax
275
        jmp     get_bin_digit
276
      bin_out_of_range:
31 halyavin 277
        or      al,al
109 heavyiron 278
        jz      get_bin_digit
279
        or      ebp,-1
280
        jmp     get_bin_digit
281
      pascal_hex_number:
31 halyavin 282
        cmp     cl,1
109 heavyiron 283
        je      bad_number
284
      get_hex_number:
31 halyavin 285
        xor     bl,bl
109 heavyiron 286
      get_hex_digit:
31 halyavin 287
        cmp     esi,[number_start]
109 heavyiron 288
        jb      number_ok
289
        movzx   eax,byte [esi]
290
        cmp     al,'x'
291
        je      hex_number_ok
292
        cmp     al,'$'
293
        je      pascal_hex_ok
294
        sub     al,30h
295
        cmp     al,9
296
        jbe     hex_digit_ok
297
        sub     al,7
298
        cmp     al,15
299
        jbe     hex_letter_digit_ok
300
        sub     al,20h
301
        cmp     al,15
302
        ja      bad_number
303
      hex_letter_digit_ok:
31 halyavin 304
        cmp     al,10
109 heavyiron 305
        jb      bad_number
306
      hex_digit_ok:
31 halyavin 307
        xor     edx,edx
109 heavyiron 308
        mov     cl,bl
309
        dec     esi
310
        cmp     bl,64
311
        je      hex_out_of_range
312
        add     bl,4
313
        cmp     cl,32
314
        jae     hex_digit_high
315
        shl     eax,cl
316
        or      dword [edi],eax
317
        jmp     get_hex_digit
318
      hex_digit_high:
31 halyavin 319
        sub     cl,32
109 heavyiron 320
        shl     eax,cl
321
        or      dword [edi+4],eax
322
        jmp     get_hex_digit
323
      hex_out_of_range:
31 halyavin 324
        or      al,al
109 heavyiron 325
        jz      get_hex_digit
326
        or      ebp,-1
327
        jmp     get_hex_digit
328
      get_oct_number:
31 halyavin 329
        xor     bl,bl
109 heavyiron 330
      get_oct_digit:
31 halyavin 331
        cmp     esi,[number_start]
109 heavyiron 332
        jb      number_ok
333
        movzx   eax,byte [esi]
334
        sub     al,30h
335
        cmp     al,7
336
        ja      bad_number
337
      oct_digit_ok:
31 halyavin 338
        xor     edx,edx
109 heavyiron 339
        mov     cl,bl
340
        dec     esi
341
        cmp     bl,64
342
        jae     oct_out_of_range
343
        add     bl,3
344
        cmp     cl,30
345
        je      oct_digit_wrap
346
        ja      oct_digit_high
347
        shl     eax,cl
348
        or      dword [edi],eax
349
        jmp     get_oct_digit
350
      oct_digit_wrap:
31 halyavin 351
        shl     eax,cl
109 heavyiron 352
        adc     dword [edi+4],0
353
        or      dword [edi],eax
354
        jmp     get_oct_digit
355
      oct_digit_high:
31 halyavin 356
        sub     cl,32
109 heavyiron 357
        shl     eax,cl
358
        or      dword [edi+4],eax
359
        jmp     get_oct_digit
360
      oct_out_of_range:
31 halyavin 361
        or      al,al
109 heavyiron 362
        jz      get_oct_digit
363
        or      ebp,-1
364
        jmp     get_oct_digit
365
      hex_number_ok:
31 halyavin 366
        dec     esi
109 heavyiron 367
      pascal_hex_ok:
31 halyavin 368
        cmp     esi,[number_start]
109 heavyiron 369
        jne     bad_number
370
      number_ok:
31 halyavin 371
        pop     esi
109 heavyiron 372
      number_done:
31 halyavin 373
        clc
109 heavyiron 374
        ret
375
      get_text_number:
31 halyavin 376
        lods    dword [esi]
109 heavyiron 377
        mov     edx,eax
378
        xor     bl,bl
379
        mov     dword [edi],0
380
        mov     dword [edi+4],0
381
      get_text_character:
31 halyavin 382
        sub     edx,1
109 heavyiron 383
        jc      number_done
384
        movzx   eax,byte [esi]
385
        inc     esi
386
        mov     cl,bl
387
        cmp     bl,64
388
        je      text_out_of_range
389
        add     bl,8
390
        cmp     cl,32
391
        jae     text_character_high
392
        shl     eax,cl
393
        or      dword [edi],eax
394
        jmp     get_text_character
395
      text_character_high:
31 halyavin 396
        sub     cl,32
109 heavyiron 397
        shl     eax,cl
398
        or      dword [edi+4],eax
399
        jmp     get_text_character
400
      text_out_of_range:
31 halyavin 401
        or      ebp,-1
109 heavyiron 402
        jmp     get_text_character
403
31 halyavin 404
 
405
        push    edi esi
109 heavyiron 406
        lods    byte [esi]
407
        cmp     al,1Ah
408
        je      fp_value_start
409
        cmp     al,'-'
410
        je      fp_sign_ok
411
        cmp     al,'+'
412
        jne     not_fp_value
413
      fp_sign_ok:
31 halyavin 414
        lods    byte [esi]
109 heavyiron 415
        cmp     al,1Ah
416
        jne     not_fp_value
417
      fp_value_start:
31 halyavin 418
        lods    byte [esi]
109 heavyiron 419
        movzx   ecx,al
420
        cmp     cl,1
421
        jbe     not_fp_value
422
        lea     edx,[esi+1]
423
        xor     ah,ah
424
      check_fp_value:
31 halyavin 425
        lods    byte [esi]
109 heavyiron 426
        cmp     al,'.'
427
        je      fp_character_dot
428
        cmp     al,'E'
429
        je      fp_character_exp
430
        cmp     al,'e'
431
        je      fp_character_exp
432
        cmp     al,'F'
433
        je      fp_last_character
434
        cmp     al,'f'
435
        je      fp_last_character
436
      digit_expected:
31 halyavin 437
        cmp     al,'0'
109 heavyiron 438
        jb      not_fp_value
439
        cmp     al,'9'
440
        ja      not_fp_value
441
        jmp     fp_character_ok
442
      fp_character_dot:
31 halyavin 443
        cmp     esi,edx
109 heavyiron 444
        je      not_fp_value
445
        or      ah,ah
446
        jnz     not_fp_value
447
        or      ah,1
448
        lods    byte [esi]
449
        loop    digit_expected
450
      not_fp_value:
31 halyavin 451
        pop     esi edi
109 heavyiron 452
        stc
453
        ret
454
      fp_last_character:
455
        cmp     cl,1
456
        jne     not_fp_value
457
        or      ah,4
458
        jmp     fp_character_ok
459
      fp_character_exp:
31 halyavin 460
        cmp     esi,edx
109 heavyiron 461
        je      not_fp_value
462
        cmp     ah,1
463
        ja      not_fp_value
464
        or      ah,2
465
        cmp     ecx,1
466
        jne     fp_character_ok
467
        cmp     byte [esi],'+'
468
        je      fp_exp_sign
469
        cmp     byte [esi],'-'
470
        jne     fp_character_ok
471
      fp_exp_sign:
31 halyavin 472
        inc     esi
109 heavyiron 473
        cmp     byte [esi],1Ah
474
        jne     not_fp_value
475
        inc     esi
476
        lods    byte [esi]
477
        movzx   ecx,al
478
        inc     ecx
479
      fp_character_ok:
31 halyavin 480
        dec     ecx
109 heavyiron 481
        jnz     check_fp_value
482
        or      ah,ah
483
        jz      not_fp_value
484
        pop     esi
485
        lods    byte [esi]
486
        mov     [fp_sign],0
487
        cmp     al,1Ah
488
        je      fp_get
489
        inc     esi
490
        cmp     al,'+'
491
        je      fp_get
492
        mov     [fp_sign],1
493
      fp_get:
31 halyavin 494
        lods    byte [esi]
109 heavyiron 495
        movzx   ecx,al
496
        xor     edx,edx
497
        mov     edi,fp_value
498
        mov     [edi],edx
499
        mov     [edi+4],edx
500
        mov     [edi+12],edx
501
        call    fp_optimize
502
        mov     [fp_format],0
503
        mov     al,[esi]
504
      fp_before_dot:
31 halyavin 505
        lods    byte [esi]
109 heavyiron 506
        cmp     al,'.'
507
        je      fp_dot
508
        cmp     al,'E'
509
        je      fp_exponent
510
        cmp     al,'e'
511
        je      fp_exponent
512
        cmp     al,'F'
513
        je      fp_done
514
        cmp     al,'f'
515
        je      fp_done
516
        sub     al,30h
517
        mov     edi,fp_value+16
518
        xor     edx,edx
519
        mov     dword [edi+12],edx
520
        mov     dword [edi],edx
521
        mov     dword [edi+4],edx
522
        mov     [edi+7],al
523
        mov     dl,7
524
        mov     dword [edi+8],edx
525
        call    fp_optimize
526
        mov     edi,fp_value
527
        push    ecx
528
        mov     ecx,10
529
        call    fp_mul
530
        pop     ecx
531
        mov     ebx,fp_value+16
532
        call    fp_add
533
        loop    fp_before_dot
534
      fp_dot:
31 halyavin 535
        mov     edi,fp_value+16
109 heavyiron 536
        xor     edx,edx
537
        mov     [edi],edx
538
        mov     [edi+4],edx
539
        mov     byte [edi+7],80h
540
        mov     [edi+8],edx
541
        mov     dword [edi+12],edx
542
        dec     ecx
543
        jz      fp_done
544
      fp_after_dot:
31 halyavin 545
        lods    byte [esi]
109 heavyiron 546
        cmp     al,'E'
547
        je      fp_exponent
548
        cmp     al,'e'
549
        je      fp_exponent
550
        cmp     al,'F'
551
        je      fp_done
552
        cmp     al,'f'
553
        je      fp_done
554
        inc     [fp_format]
555
        cmp     [fp_format],80h
556
        jne     fp_counter_ok
557
        mov     [fp_format],7Fh
558
      fp_counter_ok:
31 halyavin 559
        dec     esi
109 heavyiron 560
        mov     edi,fp_value+16
561
        push    ecx
562
        mov     ecx,10
563
        call    fp_div
564
        push    dword [edi]
565
        push    dword [edi+4]
566
        push    dword [edi+8]
567
        push    dword [edi+12]
568
        lods    byte [esi]
569
        sub     al,30h
570
        movzx   ecx,al
571
        call    fp_mul
572
        mov     ebx,edi
573
        mov     edi,fp_value
574
        call    fp_add
575
        mov     edi,fp_value+16
576
        pop     dword [edi+12]
577
        pop     dword [edi+8]
578
        pop     dword [edi+4]
579
        pop     dword [edi]
580
        pop     ecx
581
        loop    fp_after_dot
582
        jmp     fp_done
583
      fp_exponent:
31 halyavin 584
        or      [fp_format],80h
109 heavyiron 585
        xor     edx,edx
586
        xor     ebp,ebp
587
        dec     ecx
588
        jnz     get_exponent
589
        cmp     byte [esi],'+'
590
        je      fp_exponent_sign
591
        cmp     byte [esi],'-'
592
        jne     fp_done
593
        not     ebp
594
      fp_exponent_sign:
31 halyavin 595
        add     esi,2
109 heavyiron 596
        lods    byte [esi]
597
        movzx   ecx,al
598
      get_exponent:
31 halyavin 599
        movzx   eax,byte [esi]
109 heavyiron 600
        inc     esi
601
        sub     al,30h
602
        cmp     al,10
603
        jae     exponent_ok
604
        imul    edx,10
605
        cmp     edx,8000h
606
        jae     value_out_of_range
607
        add     edx,eax
608
        loop    get_exponent
609
      exponent_ok:
31 halyavin 610
        mov     edi,fp_value
109 heavyiron 611
        or      edx,edx
612
        jz      fp_done
613
        mov     ecx,edx
614
        or      ebp,ebp
615
        jnz     fp_negative_power
616
      fp_power:
31 halyavin 617
        push    ecx
109 heavyiron 618
        mov     ecx,10
619
        call    fp_mul
620
        pop     ecx
621
        loop    fp_power
622
        jmp     fp_done
623
      fp_negative_power:
31 halyavin 624
        push    ecx
109 heavyiron 625
        mov     ecx,10
626
        call    fp_div
627
        pop     ecx
628
        loop    fp_negative_power
629
      fp_done:
31 halyavin 630
        mov     edi,fp_value
109 heavyiron 631
        mov     al,[fp_format]
632
        mov     [edi+10],al
633
        mov     al,[fp_sign]
634
        mov     [edi+11],al
635
        test    byte [edi+15],80h
636
        jz      fp_ok
637
        add     dword [edi],1
638
        adc     dword [edi+4],0
639
        jnc     fp_ok
640
        mov     eax,[edi+4]
641
        shrd    [edi],eax,1
642
        shr     eax,1
643
        or      eax,80000000h
644
        mov     [edi+4],eax
645
        inc     word [edi+8]
646
      fp_ok:
31 halyavin 647
        pop     edi
109 heavyiron 648
        clc
649
        ret
650
      fp_mul:
31 halyavin 651
        or      ecx,ecx
109 heavyiron 652
        jz      fp_zero
653
        mov     eax,[edi+12]
654
        mul     ecx
655
        mov     [edi+12],eax
656
        mov     ebx,edx
657
        mov     eax,[edi]
658
        mul     ecx
659
        add     eax,ebx
660
        adc     edx,0
661
        mov     [edi],eax
662
        mov     ebx,edx
663
        mov     eax,[edi+4]
664
        mul     ecx
665
        add     eax,ebx
666
        adc     edx,0
667
        mov     [edi+4],eax
668
      .loop:
31 halyavin 669
        or      edx,edx
109 heavyiron 670
        jz      .done
671
        mov     eax,[edi]
672
        shrd    [edi+12],eax,1
673
        mov     eax,[edi+4]
674
        shrd    [edi],eax,1
675
        shrd    eax,edx,1
676
        mov     [edi+4],eax
677
        shr     edx,1
678
        inc     dword [edi+8]
679
        cmp     dword [edi+8],8000h
680
        jge     value_out_of_range
681
        jmp     .loop
682
      .done:
31 halyavin 683
        ret
109 heavyiron 684
      fp_div:
31 halyavin 685
        mov     eax,[edi+4]
109 heavyiron 686
        xor     edx,edx
687
        div     ecx
688
        mov     [edi+4],eax
689
        mov     eax,[edi]
690
        div     ecx
691
        mov     [edi],eax
692
        mov     eax,[edi+12]
693
        div     ecx
694
        mov     [edi+12],eax
695
        mov     ebx,eax
696
        or      ebx,[edi]
697
        or      ebx,[edi+4]
698
        jz      fp_zero
699
      .loop:
31 halyavin 700
        test    byte [edi+7],80h
109 heavyiron 701
        jnz     .exp_ok
702
        mov     eax,[edi]
703
        shld    [edi+4],eax,1
704
        mov     eax,[edi+12]
705
        shld    [edi],eax,1
706
        add     eax,eax
707
        mov     [edi+12],eax
708
        dec     dword [edi+8]
709
        add     edx,edx
710
        jmp     .loop
711
      .exp_ok:
31 halyavin 712
        mov     eax,edx
109 heavyiron 713
        xor     edx,edx
714
        div     ecx
715
        add     [edi+12],eax
716
        adc     dword [edi],0
717
        adc     dword [edi+4],0
718
        jnc     .done
719
        mov     eax,[edi+4]
720
        mov     ebx,[edi]
721
        shrd    [edi],eax,1
722
        shrd    [edi+12],ebx,1
723
        shr     eax,1
724
        or      eax,80000000h
725
        mov     [edi+4],eax
726
        inc     dword [edi+8]
727
      .done:
31 halyavin 728
        ret
109 heavyiron 729
      fp_add:
31 halyavin 730
        cmp     dword [ebx+8],8000h
109 heavyiron 731
        je      .done
732
        cmp     dword [edi+8],8000h
733
        je      .copy
734
        mov     eax,[ebx+8]
735
        cmp     eax,[edi+8]
736
        jge     .exp_ok
737
        mov     eax,[edi+8]
738
      .exp_ok:
31 halyavin 739
        call    .change_exp
109 heavyiron 740
        xchg    ebx,edi
741
        call    .change_exp
742
        xchg    ebx,edi
743
        mov     edx,[ebx+12]
744
        mov     eax,[ebx]
745
        mov     ebx,[ebx+4]
746
        add     [edi+12],edx
747
        adc     [edi],eax
748
        adc     [edi+4],ebx
749
        jnc     .done
750
        mov     eax,[edi]
751
        shrd    [edi+12],eax,1
752
        mov     eax,[edi+4]
753
        shrd    [edi],eax,1
754
        shr     eax,1
755
        or      eax,80000000h
756
        mov     [edi+4],eax
757
        inc     dword [edi+8]
758
      .done:
31 halyavin 759
        ret
109 heavyiron 760
      .copy:
31 halyavin 761
        mov     eax,[ebx]
109 heavyiron 762
        mov     [edi],eax
763
        mov     eax,[ebx+4]
764
        mov     [edi+4],eax
765
        mov     eax,[ebx+8]
766
        mov     [edi+8],eax
767
        mov     eax,[ebx+12]
768
        mov     [edi+12],eax
769
        ret
770
      .change_exp:
31 halyavin 771
        push    ecx
109 heavyiron 772
        mov     ecx,eax
773
        sub     ecx,[ebx+8]
774
        mov     edx,[ebx+4]
775
        jecxz   .exp_done
776
      .exp_loop:
31 halyavin 777
        mov     ebp,[ebx]
109 heavyiron 778
        shrd    [ebx+12],ebp,1
779
        shrd    [ebx],edx,1
780
        shr     edx,1
781
        inc     dword [ebx+8]
782
        loop    .exp_loop
783
      .exp_done:
31 halyavin 784
        mov     [ebx+4],edx
109 heavyiron 785
        pop     ecx
786
        ret
787
      fp_optimize:
31 halyavin 788
        mov     eax,[edi]
109 heavyiron 789
        mov     ebp,[edi+4]
790
        or      ebp,[edi]
791
        or      ebp,[edi+12]
792
        jz      fp_zero
793
      .loop:
31 halyavin 794
        test    byte [edi+7],80h
109 heavyiron 795
        jnz     .done
796
        shld    [edi+4],eax,1
797
        mov     ebp,[edi+12]
798
        shld    eax,ebp,1
799
        mov     [edi],eax
800
        shl     dword [edi+12],1
801
        dec     dword [edi+8]
802
        jmp     .loop
803
      .done:
31 halyavin 804
        ret
109 heavyiron 805
      fp_zero:
31 halyavin 806
        mov     dword [edi+8],8000h
109 heavyiron 807
        ret
808
31 halyavin 809
 
810
        mov     [current_offset],edi
109 heavyiron 811
        mov     [value_undefined],0
812
        cmp     byte [esi],0
813
        je      get_string_value
814
        cmp     byte [esi],'.'
815
        je      convert_fp
816
      calculation_loop:
31 halyavin 817
        lods    byte [esi]
109 heavyiron 818
        cmp     al,1
819
        je      get_byte_number
820
        cmp     al,2
821
        je      get_word_number
822
        cmp     al,4
823
        je      get_dword_number
824
        cmp     al,8
825
        je      get_qword_number
826
        cmp     al,0Fh
827
        je      value_out_of_range
828
        cmp     al,10h
829
        je      get_register
830
        cmp     al,11h
831
        je      get_label
832
        cmp     al,')'
833
        je      expression_calculated
834
        cmp     al,']'
835
        je      expression_calculated
836
        cmp     al,'!'
837
        je      invalid_expression
838
        sub     edi,14h
839
        mov     ebx,edi
840
        sub     ebx,14h
841
        cmp     al,0E0h
842
        je      calculate_rva
843
        cmp     al,0D0h
844
        je      calculate_not
845
        cmp     al,083h
846
        je      calculate_neg
847
        mov     dx,[ebx+8]
848
        or      dx,[edi+8]
849
        cmp     al,80h
850
        je      calculate_add
851
        cmp     al,81h
852
        je      calculate_sub
853
        mov     ah,[ebx+12]
854
        or      ah,[edi+12]
855
        jz      absolute_values_calculation
856
        cmp     [error_line],0
857
        jne     absolute_values_calculation
858
        mov     eax,[current_line]
859
        mov     [error_line],eax
860
        mov     [error],invalid_use_of_symbol
861
      absolute_values_calculation:
31 halyavin 862
        cmp     al,90h
109 heavyiron 863
        je      calculate_mul
864
        cmp     al,91h
865
        je      calculate_div
866
        or      dx,dx
867
        jnz     invalid_expression
868
        cmp     al,0A0h
869
        je      calculate_mod
870
        cmp     al,0B0h
871
        je      calculate_and
872
        cmp     al,0B1h
873
        je      calculate_or
874
        cmp     al,0B2h
875
        je      calculate_xor
876
        cmp     al,0C0h
877
        je      calculate_shl
878
        cmp     al,0C1h
879
        je      calculate_shr
880
        jmp     invalid_expression
881
      expression_calculated:
31 halyavin 882
        sub     edi,14h
109 heavyiron 883
        cmp     [value_undefined],0
884
        je      expression_value_ok
885
        xor     eax,eax
886
        mov     [edi],eax
887
        mov     [edi+4],eax
888
        mov     [edi+12],al
889
      expression_value_ok:
31 halyavin 890
        ret
109 heavyiron 891
      get_byte_number:
31 halyavin 892
        mov     word [edi+8],0
109 heavyiron 893
        mov     byte [edi+12],0
894
        xor     eax,eax
895
        lods    byte [esi]
896
        stos    dword [edi]
897
        xor     al,al
898
        stos    dword [edi]
899
        add     edi,0Ch
900
        jmp     calculation_loop
901
      get_word_number:
31 halyavin 902
        mov     word [edi+8],0
109 heavyiron 903
        mov     byte [edi+12],0
904
        xor     eax,eax
905
        lods    word [esi]
906
        stos    dword [edi]
907
        xor     ax,ax
908
        stos    dword [edi]
909
        add     edi,0Ch
910
        jmp     calculation_loop
911
      get_dword_number:
31 halyavin 912
        mov     word [edi+8],0
109 heavyiron 913
        mov     byte [edi+12],0
914
        movs    dword [edi],[esi]
915
        xor     eax,eax
916
        stos    dword [edi]
917
        add     edi,0Ch
918
        jmp     calculation_loop
919
      get_qword_number:
31 halyavin 920
        mov     word [edi+8],0
109 heavyiron 921
        mov     byte [edi+12],0
922
        movs    dword [edi],[esi]
923
        movs    dword [edi],[esi]
924
        add     edi,0Ch
925
        jmp     calculation_loop
926
      get_register:
31 halyavin 927
        mov     byte [edi+9],0
109 heavyiron 928
        mov     byte [edi+12],0
929
        lods    byte [esi]
930
        mov     [edi+8],al
931
        mov     byte [edi+10],1
932
        xor     eax,eax
933
        stos    dword [edi]
934
        stos    dword [edi]
935
        add     edi,0Ch
936
        jmp     calculation_loop
937
      get_label:
31 halyavin 938
        xor     eax,eax
109 heavyiron 939
        mov     [edi+8],eax
940
        mov     [edi+12],al
941
        mov     [edi+20],eax
942
        lods    dword [esi]
943
        cmp     eax,0Fh
944
        jb      predefined_label
945
        je      reserved_word_used_as_symbol
946
        mov     ebx,eax
947
        mov     ax,[current_pass]
948
        mov     [ebx+18],ax
949
        or      byte [ebx+8],8
950
        test    byte [ebx+8],1
951
        jz      label_undefined
952
        cmp     ax,[ebx+16]
953
        je      label_defined
954
        test    byte [ebx+8],4
955
        jnz     label_undefined
956
        test    byte [ebx+9],1
957
        jz      label_defined
958
        mov     eax,[ebx]
959
        sub     eax,dword [adjustment]
960
        stos    dword [edi]
961
        mov     eax,[ebx+4]
962
        sbb     eax,dword [adjustment+4]
963
        stos    dword [edi]
964
        mov     eax,dword [adjustment]
965
        or      eax,dword [adjustment+4]
966
        jz      got_label
967
        or      [next_pass_needed],-1
968
        jmp     got_label
969
      label_defined:
31 halyavin 970
        mov     eax,[ebx]
109 heavyiron 971
        stos    dword [edi]
972
        mov     eax,[ebx+4]
973
        stos    dword [edi]
974
      got_label:
31 halyavin 975
        mov     al,[ebx+11]
109 heavyiron 976
        mov     [edi-8+12],al
977
        mov     eax,[ebx+12]
978
        mov     [edi-8+8],eax
979
        mov     eax,[ebx+20]
980
        mov     [edi-8+16],eax
981
        add     edi,0Ch
982
        mov     al,[ebx+10]
983
        or      al,al
984
        jz      calculation_loop
985
        cmp     [size_override],-1
986
        je      calculation_loop
987
        cmp     [size_override],0
988
        je      check_size
989
        cmp     [operand_size],0
990
        jne     calculation_loop
991
        mov     [operand_size],al
992
        jmp     calculation_loop
993
      check_size:
31 halyavin 994
        xchg    [operand_size],al
109 heavyiron 995
        or      al,al
996
        jz      calculation_loop
997
        cmp     al,[operand_size]
998
        jne     operand_sizes_do_not_match
999
        jmp     calculation_loop
1000
      current_offset_label:
31 halyavin 1001
        mov     al,[labels_type]
109 heavyiron 1002
        mov     [edi+12],al
1003
        mov     eax,[org_symbol]
1004
        mov     [edi+16],eax
1005
        mov     eax,[current_offset]
1006
        xor     edx,edx
1007
        sub     eax,dword [org_origin]
1008
        sbb     edx,dword [org_origin+4]
1009
        stos    dword [edi]
1010
        mov     eax,edx
1011
        stos    dword [edi]
1012
        mov     eax,[org_registers]
1013
        stos    dword [edi]
1014
        add     edi,8
1015
        jmp     calculation_loop
1016
      org_origin_label:
31 halyavin 1017
        mov     al,[labels_type]
109 heavyiron 1018
        mov     [edi+12],al
1019
        mov     eax,[org_symbol]
1020
        mov     [edi+16],eax
1021
        mov     eax,[org_start]
1022
        xor     edx,edx
1023
        sub     eax,dword [org_origin]
1024
        sbb     edx,dword [org_origin+4]
1025
        stos    dword [edi]
1026
        mov     eax,edx
1027
        stos    dword [edi]
1028
        mov     eax,[org_registers]
1029
        stos    dword [edi]
1030
        add     edi,8
1031
        jmp     calculation_loop
1032
      counter_label:
31 halyavin 1033
        mov     eax,[counter]
109 heavyiron 1034
      make_dword_label_value:
31 halyavin 1035
        stos    dword [edi]
109 heavyiron 1036
        xor     eax,eax
1037
        stos    dword [edi]
1038
        add     edi,0Ch
1039
        jmp     calculation_loop
1040
      timestamp_label:
31 halyavin 1041
        call    make_timestamp
109 heavyiron 1042
        jmp     make_dword_label_value
1043
      predefined_label:
31 halyavin 1044
        or      eax,eax
109 heavyiron 1045
        jz      current_offset_label
1046
        cmp     eax,1
1047
        je      counter_label
1048
        cmp     eax,2
1049
        je      timestamp_label
1050
        cmp     eax,3
1051
        je      org_origin_label
1052
      label_undefined:
31 halyavin 1053
        cmp     [current_pass],1
109 heavyiron 1054
        ja      undefined_value
1055
      force_next_pass:
31 halyavin 1056
        or      [next_pass_needed],-1
109 heavyiron 1057
      undefined_value:
31 halyavin 1058
        mov     byte [edi+12],0
109 heavyiron 1059
        or      [value_undefined],-1
1060
        xor     eax,eax
1061
        stos    dword [edi]
1062
        stos    dword [edi]
1063
        add     edi,0Ch
1064
        cmp     [error_line],0
1065
        jne     calculation_loop
1066
        mov     eax,[current_line]
1067
        mov     [error_line],eax
1068
        mov     [error],undefined_symbol
1069
        jmp     calculation_loop
1070
      calculate_add:
31 halyavin 1071
        mov     ecx,[ebx+16]
109 heavyiron 1072
        cmp     byte [edi+12],0
1073
        je      add_values
1074
        mov     ecx,[edi+16]
1075
        cmp     byte [ebx+12],0
1076
        je      add_values
1077
        cmp     [error_line],0
1078
        jne     add_values
1079
        mov     eax,[current_line]
1080
        mov     [error_line],eax
1081
        mov     [error],invalid_use_of_symbol
1082
      add_values:
31 halyavin 1083
        mov     al,[edi+12]
109 heavyiron 1084
        or      [ebx+12],al
1085
        mov     [ebx+16],ecx
1086
        mov     eax,[edi]
1087
        add     [ebx],eax
1088
        mov     eax,[edi+4]
1089
        adc     [ebx+4],eax
1090
        or      dx,dx
1091
        jz      calculation_loop
1092
        push    esi
1093
        mov     esi,ebx
1094
        lea     ebx,[edi+10]
1095
        mov     cl,[edi+8]
1096
        call    add_register
1097
        lea     ebx,[edi+11]
1098
        mov     cl,[edi+9]
1099
        call    add_register
1100
        pop     esi
1101
        jmp     calculation_loop
1102
      add_register:
31 halyavin 1103
        or      cl,cl
109 heavyiron 1104
        jz      add_register_done
1105
      add_register_start:
31 halyavin 1106
        cmp     [esi+8],cl
109 heavyiron 1107
        jne     add_in_second_slot
1108
        mov     al,[ebx]
1109
        add     [esi+10],al
1110
        jnz     add_register_done
1111
        mov     byte [esi+8],0
1112
        ret
1113
      add_in_second_slot:
31 halyavin 1114
        cmp     [esi+9],cl
109 heavyiron 1115
        jne     create_in_first_slot
1116
        mov     al,[ebx]
1117
        add     [esi+11],al
1118
        jnz     add_register_done
1119
        mov     byte [esi+9],0
1120
        ret
1121
      create_in_first_slot:
31 halyavin 1122
        cmp     byte [esi+8],0
109 heavyiron 1123
        jne     create_in_second_slot
1124
        mov     [esi+8],cl
1125
        mov     al,[ebx]
1126
        mov     [esi+10],al
1127
        ret
1128
      create_in_second_slot:
31 halyavin 1129
        cmp     byte [esi+9],0
109 heavyiron 1130
        jne     invalid_expression
1131
        mov     [esi+9],cl
1132
        mov     al,[ebx]
1133
        mov     [esi+11],al
1134
      add_register_done:
31 halyavin 1135
        ret
109 heavyiron 1136
      calculate_sub:
31 halyavin 1137
        xor     ah,ah
109 heavyiron 1138
        mov     ah,[ebx+12]
1139
        mov     al,[edi+12]
1140
        or      al,al
1141
        jz      sub_values
1142
        cmp     al,ah
1143
        jne     invalid_sub
1144
        xor     ah,ah
1145
        mov     ecx,[edi+16]
1146
        cmp     ecx,[ebx+16]
1147
        je      sub_values
1148
        cmp     ecx,[org_symbol]
1149
        jne     invalid_sub
1150
        test    byte [ebx+12],1
1151
        jnz     invalid_sub
1152
        mov     ah,3
1153
      sub_values:
31 halyavin 1154
        mov     [ebx+12],ah
109 heavyiron 1155
        mov     eax,[edi]
1156
        sub     [ebx],eax
1157
        mov     eax,[edi+4]
1158
        sbb     [ebx+4],eax
1159
        or      dx,dx
1160
        jz      calculation_loop
1161
        push    esi
1162
        mov     esi,ebx
1163
        lea     ebx,[edi+10]
1164
        mov     cl,[edi+8]
1165
        call    sub_register
1166
        lea     ebx,[edi+11]
1167
        mov     cl,[edi+9]
1168
        call    sub_register
1169
        pop     esi
1170
        jmp     calculation_loop
1171
      invalid_sub:
31 halyavin 1172
        cmp     [error_line],0
109 heavyiron 1173
        jne     sub_values
1174
        mov     eax,[current_line]
1175
        mov     [error_line],eax
1176
        mov     [error],invalid_use_of_symbol
1177
        jmp     sub_values
1178
      sub_register:
31 halyavin 1179
        or      cl,cl
109 heavyiron 1180
        jz      add_register_done
1181
        neg     byte [ebx]
1182
        jmp     add_register_start
1183
      calculate_mul:
31 halyavin 1184
        or      dx,dx
109 heavyiron 1185
        jz      mul_start
1186
        cmp     word [ebx+8],0
1187
        jne     mul_start
1188
        mov     eax,[ebx]
1189
        xchg    eax,[edi]
1190
        mov     [ebx],eax
1191
        mov     eax,[ebx+4]
1192
        xchg    eax,[edi+4]
1193
        mov     [ebx+4],eax
1194
        mov     eax,[ebx+8]
1195
        xchg    eax,[edi+8]
1196
        mov     [ebx+8],eax
1197
        mov     eax,[ebx+12]
1198
        xchg    eax,[edi+12]
1199
        mov     [ebx+12],eax
1200
      mul_start:
31 halyavin 1201
        push    esi edx
109 heavyiron 1202
        mov     esi,ebx
1203
        xor     bl,bl
1204
        bt      dword [esi+4],31
1205
        jnc     mul_first_sign_ok
1206
        not     dword [esi]
1207
        not     dword [esi+4]
1208
        add     dword [esi],1
1209
        adc     dword [esi+4],0
1210
        not     bl
1211
      mul_first_sign_ok:
31 halyavin 1212
        bt      dword [edi+4],31
109 heavyiron 1213
        jnc     mul_second_sign_ok
1214
        not     dword [edi]
1215
        not     dword [edi+4]
1216
        add     dword [edi],1
1217
        adc     dword [edi+4],0
1218
        not     bl
1219
      mul_second_sign_ok:
31 halyavin 1220
        cmp     dword [esi+4],0
109 heavyiron 1221
        jz      mul_numbers
1222
        cmp     dword [edi+4],0
1223
        jnz     value_out_of_range
1224
      mul_numbers:
31 halyavin 1225
        mov     eax,[esi+4]
109 heavyiron 1226
        mul     dword [edi]
1227
        or      edx,edx
1228
        jnz     value_out_of_range
1229
        mov     ecx,eax
1230
        mov     eax,[esi]
1231
        mul     dword [edi+4]
1232
        or      edx,edx
1233
        jnz     value_out_of_range
1234
        add     ecx,eax
1235
        jc      value_out_of_range
1236
        mov     eax,[esi]
1237
        mul     dword [edi]
1238
        add     edx,ecx
1239
        jc      value_out_of_range
1240
        test    edx,1 shl 31
1241
        jnz     value_out_of_range
1242
        mov     [esi],eax
1243
        mov     [esi+4],edx
1244
        or      bl,bl
1245
        jz      mul_ok
1246
        not     dword [esi]
1247
        not     dword [esi+4]
1248
        add     dword [esi],1
1249
        adc     dword [esi+4],0
1250
      mul_ok:
31 halyavin 1251
        pop     edx
109 heavyiron 1252
        or      dx,dx
1253
        jz      mul_calculated
1254
        cmp     word [edi+8],0
1255
        jne     invalid_value
1256
        cmp     byte [esi+8],0
1257
        je      mul_first_register_ok
1258
        mov     al,[edi]
1259
        cbw
1260
        cwde
1261
        cdq
1262
        cmp     edx,[edi+4]
1263
        jne     value_out_of_range
1264
        cmp     eax,[edi]
1265
        jne     value_out_of_range
1266
        imul    byte [esi+10]
1267
        mov     dl,ah
1268
        cbw
1269
        cmp     ah,dl
1270
        jne     value_out_of_range
1271
        mov     [esi+10],al
1272
      mul_first_register_ok:
31 halyavin 1273
        cmp     byte [esi+9],0
109 heavyiron 1274
        je      mul_calculated
1275
        mov     al,[edi]
1276
        cbw
1277
        cwde
1278
        cdq
1279
        cmp     edx,[edi+4]
1280
        jne     value_out_of_range
1281
        cmp     eax,[edi]
1282
        jne     value_out_of_range
1283
        imul    byte [esi+11]
1284
        mov     dl,ah
1285
        cbw
1286
        cmp     ah,dl
1287
        jne     value_out_of_range
1288
        mov     [esi+11],al
1289
      mul_calculated:
31 halyavin 1290
        pop     esi
109 heavyiron 1291
        jmp     calculation_loop
1292
      calculate_div:
31 halyavin 1293
        push    esi edx
109 heavyiron 1294
        mov     esi,ebx
1295
        call    div_64
1296
        pop     edx
1297
        or      dx,dx
1298
        jz      div_calculated
1299
        cmp     byte [esi+8],0
1300
        je      div_first_register_ok
1301
        mov     al,[edi]
1302
        cbw
1303
        cwde
1304
        cdq
1305
        cmp     edx,[edi+4]
1306
        jne     value_out_of_range
1307
        cmp     eax,[edi]
1308
        jne     value_out_of_range
1309
        or      al,al
1310
        jz      value_out_of_range
1311
        mov     al,[esi+10]
1312
        cbw
1313
        idiv    byte [edi]
1314
        or      ah,ah
1315
        jnz     invalid_use_of_symbol
1316
        mov     [esi+10],al
1317
      div_first_register_ok:
31 halyavin 1318
        cmp     byte [esi+9],0
109 heavyiron 1319
        je      div_calculated
1320
        mov     al,[edi]
1321
        cbw
1322
        cwde
1323
        cdq
1324
        cmp     edx,[edi+4]
1325
        jne     value_out_of_range
1326
        cmp     eax,[edi]
1327
        jne     value_out_of_range
1328
        or      al,al
1329
        jz      value_out_of_range
1330
        mov     al,[esi+11]
1331
        cbw
1332
        idiv    byte [edi]
1333
        or      ah,ah
1334
        jnz     invalid_use_of_symbol
1335
        mov     [esi+11],al
1336
      div_calculated:
31 halyavin 1337
        pop     esi
109 heavyiron 1338
        jmp     calculation_loop
1339
      calculate_mod:
31 halyavin 1340
        push    esi
109 heavyiron 1341
        mov     esi,ebx
1342
        call    div_64
1343
        mov     [esi],eax
1344
        mov     [esi+4],edx
1345
        pop     esi
1346
        jmp     calculation_loop
1347
      calculate_and:
31 halyavin 1348
        mov     eax,[edi]
109 heavyiron 1349
        and     [ebx],eax
1350
        mov     eax,[edi+4]
1351
        and     [ebx+4],eax
1352
        jmp     calculation_loop
1353
      calculate_or:
31 halyavin 1354
        mov     eax,[edi]
109 heavyiron 1355
        or      [ebx],eax
1356
        mov     eax,[edi+4]
1357
        or      [ebx+4],eax
1358
        jmp     calculation_loop
1359
      calculate_xor:
31 halyavin 1360
        mov     eax,[edi]
109 heavyiron 1361
        xor     [ebx],eax
1362
        mov     eax,[edi+4]
1363
        xor     [ebx+4],eax
1364
        jmp     calculation_loop
1365
      shr_negative:
31 halyavin 1366
        not     dword [edi]
109 heavyiron 1367
        not     dword [edi+4]
1368
        add     dword [edi],1
1369
        adc     dword [edi+4],0
1370
      calculate_shl:
31 halyavin 1371
        mov     eax,dword [edi+4]
109 heavyiron 1372
        bt      eax,31
1373
        jc      shl_negative
1374
        or      eax,eax
1375
        jnz     zero_value
1376
        mov     ecx,[edi]
1377
        cmp     ecx,64
1378
        jae     zero_value
1379
        cmp     ecx,32
1380
        jae     shl_high
1381
        mov     edx,[ebx+4]
1382
        mov     eax,[ebx]
1383
        shld    edx,eax,cl
1384
        shl     eax,cl
1385
        mov     [ebx],eax
1386
        mov     [ebx+4],edx
1387
        jmp     calculation_loop
1388
      shl_high:
31 halyavin 1389
        sub     cl,32
109 heavyiron 1390
        mov     eax,[ebx]
1391
        shl     eax,cl
1392
        mov     [ebx+4],eax
1393
        mov     dword [ebx],0
1394
        jmp     calculation_loop
1395
      shl_negative:
31 halyavin 1396
        not     dword [edi]
109 heavyiron 1397
        not     dword [edi+4]
1398
        add     dword [edi],1
1399
        adc     dword [edi+4],0
1400
      calculate_shr:
31 halyavin 1401
        mov     eax,dword [edi+4]
109 heavyiron 1402
        bt      eax,31
1403
        jc      shr_negative
1404
        or      eax,eax
1405
        jnz     zero_value
1406
        mov     ecx,[edi]
1407
        cmp     ecx,64
1408
        jae     zero_value
1409
        cmp     ecx,32
1410
        jae     shr_high
1411
        mov     edx,[ebx+4]
1412
        mov     eax,[ebx]
1413
        shrd    eax,edx,cl
1414
        shr     edx,cl
1415
        mov     [ebx],eax
1416
        mov     [ebx+4],edx
1417
        jmp     calculation_loop
1418
      shr_high:
31 halyavin 1419
        sub     cl,32
109 heavyiron 1420
        mov     eax,[ebx+4]
1421
        shr     eax,cl
1422
        mov     [ebx],eax
1423
        mov     dword [ebx+4],0
1424
        jmp     calculation_loop
1425
      zero_value:
31 halyavin 1426
        mov     dword [ebx],0
109 heavyiron 1427
        mov     dword [ebx+4],0
1428
        jmp     calculation_loop
1429
      calculate_not:
31 halyavin 1430
        cmp     word [edi+8],0
109 heavyiron 1431
        jne     invalid_expression
1432
        cmp     byte [edi+12],0
1433
        je      not_ok
1434
        cmp     [error_line],0
1435
        jne     not_ok
1436
        mov     eax,[current_line]
1437
        mov     [error_line],eax
1438
        mov     [error],invalid_use_of_symbol
1439
      not_ok:
31 halyavin 1440
        cmp     [value_size],1
109 heavyiron 1441
        je      not_byte
1442
        cmp     [value_size],2
1443
        je      not_word
1444
        cmp     [value_size],4
1445
        je      not_dword
1446
        cmp     [value_size],6
1447
        je      not_pword
1448
      not_qword:
31 halyavin 1449
        not     dword [edi]
109 heavyiron 1450
        not     dword [edi+4]
1451
        add     edi,14h
1452
        jmp     calculation_loop
1453
      not_byte:
31 halyavin 1454
        cmp     dword [edi+4],0
109 heavyiron 1455
        jne     not_qword
1456
        cmp     word [edi+2],0
1457
        jne     not_qword
1458
        cmp     byte [edi+1],0
1459
        jne     not_qword
1460
        not     byte [edi]
1461
        add     edi,14h
1462
        jmp     calculation_loop
1463
      not_word:
31 halyavin 1464
        cmp     dword [edi+4],0
109 heavyiron 1465
        jne     not_qword
1466
        cmp     word [edi+2],0
1467
        jne     not_qword
1468
        not     word [edi]
1469
        add     edi,14h
1470
        jmp     calculation_loop
1471
      not_dword:
31 halyavin 1472
        cmp     dword [edi+4],0
109 heavyiron 1473
        jne     not_qword
1474
        not     dword [edi]
1475
        add     edi,14h
1476
        jmp     calculation_loop
1477
      not_pword:
31 halyavin 1478
        cmp     word [edi+6],0
109 heavyiron 1479
        jne     not_qword
1480
        not     dword [edi]
1481
        not     word [edi+4]
1482
        add     edi,14h
1483
        jmp     calculation_loop
1484
      calculate_neg:
31 halyavin 1485
        cmp     word [edi+8],0
109 heavyiron 1486
        jne     invalid_expression
1487
        cmp     byte [edi+12],0
1488
        je      neg_ok
1489
        cmp     [error_line],0
1490
        jne     neg_ok
1491
        mov     eax,[current_line]
1492
        mov     [error_line],eax
1493
        mov     [error],invalid_use_of_symbol
1494
      neg_ok:
31 halyavin 1495
        mov     eax,[edi]
109 heavyiron 1496
        mov     edx,[edi+4]
1497
        mov     dword [edi],0
1498
        mov     dword [edi+4],0
1499
        sub     [edi],eax
1500
        sbb     [edi+4],edx
1501
        add     edi,14h
1502
        jmp     calculation_loop
1503
      calculate_rva:
31 halyavin 1504
        cmp     word [edi+8],0
109 heavyiron 1505
        jne     invalid_expression
1506
        cmp     [output_format],5
1507
        je      calculate_gotoff
1508
        cmp     [output_format],3
1509
        jne     invalid_expression
1510
        test    [format_flags],8
1511
        jnz     pe64_rva
1512
        mov     al,2
1513
        bt      [resolver_flags],0
1514
        jc      rva_type_ok
1515
        xor     al,al
1516
      rva_type_ok:
1517
        cmp     byte [edi+12],al
1518
        je      rva_ok
1519
        cmp     [error_line],0
1520
        jne     rva_ok
1521
        mov     eax,[current_line]
1522
        mov     [error_line],eax
1523
        mov     [error],invalid_use_of_symbol
1524
      rva_ok:
31 halyavin 1525
        mov     byte [edi+12],0
109 heavyiron 1526
        mov     eax,[code_start]
1527
        mov     eax,[eax+34h]
1528
        cdq
1529
        sub     [edi],eax
1530
        sbb     [edi+4],edx
1531
        add     edi,14h
1532
        jmp     calculation_loop
1533
      pe64_rva:
31 halyavin 1534
        mov     al,4
109 heavyiron 1535
        bt      [resolver_flags],0
1536
        jc      pe64_rva_type_ok
1537
        xor     al,al
1538
      pe64_rva_type_ok:
1539
        cmp     byte [edi+12],al
1540
        je      pe64_rva_ok
1541
        cmp     [error_line],0
1542
        jne     pe64_rva_ok
1543
        mov     eax,[current_line]
1544
        mov     [error_line],eax
1545
        mov     [error],invalid_use_of_symbol
1546
      pe64_rva_ok:
31 halyavin 1547
        mov     byte [edi+12],0
109 heavyiron 1548
        mov     eax,[code_start]
1549
        mov     edx,[eax+34h]
1550
        mov     eax,[eax+30h]
1551
        sub     [edi],eax
1552
        sbb     [edi+4],edx
1553
        add     edi,14h
1554
        jmp     calculation_loop
1555
      calculate_gotoff:
1556
        test    [format_flags],8+1
1557
        jnz     invalid_expression
1558
        cmp     byte [edi+12],2
1559
        je      gotoff_ok
1560
        cmp     [error_line],0
1561
        jne     pe64_rva_ok
1562
        mov     eax,[current_line]
1563
        mov     [error_line],eax
1564
        mov     [error],invalid_use_of_symbol
1565
      gotoff_ok:
1566
        mov     byte [edi+12],5
1567
        add     edi,14h
1568
        jmp     calculation_loop
1569
      div_64:
31 halyavin 1570
        xor     ebx,ebx
109 heavyiron 1571
        cmp     dword [edi],0
1572
        jne     divider_ok
1573
        cmp     dword [edi+4],0
1574
        jne     divider_ok
1575
        cmp     [next_pass_needed],0
1576
        je      value_out_of_range
1577
        jmp     div_done
1578
      divider_ok:
31 halyavin 1579
        bt      dword [esi+4],31
109 heavyiron 1580
        jnc     div_first_sign_ok
1581
        not     dword [esi]
1582
        not     dword [esi+4]
1583
        add     dword [esi],1
1584
        adc     dword [esi+4],0
1585
        not     bx
1586
      div_first_sign_ok:
31 halyavin 1587
        bt      dword [edi+4],31
109 heavyiron 1588
        jnc     div_second_sign_ok
1589
        not     dword [edi]
1590
        not     dword [edi+4]
1591
        add     dword [edi],1
1592
        adc     dword [edi+4],0
1593
        not     bl
1594
      div_second_sign_ok:
31 halyavin 1595
        cmp     dword [edi+4],0
109 heavyiron 1596
        jne     div_high
1597
        mov     ecx,[edi]
1598
        mov     eax,[esi+4]
1599
        xor     edx,edx
1600
        div     ecx
1601
        mov     [esi+4],eax
1602
        mov     eax,[esi]
1603
        div     ecx
1604
        mov     [esi],eax
1605
        mov     eax,edx
1606
        xor     edx,edx
1607
        jmp     div_done
1608
      div_high:
31 halyavin 1609
        mov     eax,[esi+4]
109 heavyiron 1610
        xor     edx,edx
1611
        div     dword [edi+4]
1612
        mov     ebx,[esi]
1613
        mov     [esi],eax
1614
        mov     dword [esi+4],0
1615
        mov     ecx,edx
1616
        mul     dword [edi]
1617
      div_high_loop:
31 halyavin 1618
        cmp     ecx,edx
109 heavyiron 1619
        ja      div_high_done
1620
        jb      div_high_large_correction
1621
        cmp     ebx,eax
1622
        jae     div_high_done
1623
      div_high_correction:
31 halyavin 1624
        dec     dword [esi]
109 heavyiron 1625
        sub     eax,[edi]
1626
        sbb     edx,[edi+4]
1627
        jnc     div_high_loop
1628
      div_high_done:
31 halyavin 1629
        sub     ebx,eax
109 heavyiron 1630
        sbb     ecx,edx
1631
        mov     edx,ecx
1632
        mov     eax,ebx
1633
        ret
1634
      div_high_large_correction:
31 halyavin 1635
        push    eax edx
109 heavyiron 1636
        mov     eax,edx
1637
        sub     eax,ecx
1638
        xor     edx,edx
1639
        div     dword [edi+4]
1640
        shr     eax,1
1641
        jz      div_high_small_correction
1642
        sub     [esi],eax
1643
        push    eax
1644
        mul     dword [edi+4]
1645
        sub     dword [esp+4],eax
1646
        pop     eax
1647
        mul     dword [edi]
1648
        sub     dword [esp+4],eax
1649
        sbb     dword [esp],edx
1650
        pop     edx eax
1651
        jmp     div_high_loop
1652
      div_high_small_correction:
31 halyavin 1653
        pop     edx eax
109 heavyiron 1654
        jmp     div_high_correction
1655
      div_done:
31 halyavin 1656
        or      bh,bh
109 heavyiron 1657
        jz      remainder_ok
1658
        not     eax
1659
        not     edx
1660
        add     eax,1
1661
        adc     edx,0
1662
      remainder_ok:
31 halyavin 1663
        or      bl,bl
109 heavyiron 1664
        jz      div_ok
1665
        not     dword [esi]
1666
        not     dword [esi+4]
1667
        add     dword [esi],1
1668
        adc     dword [esi+4],0
1669
      div_ok:
31 halyavin 1670
        ret
109 heavyiron 1671
      convert_fp:
31 halyavin 1672
        inc     esi
109 heavyiron 1673
        mov     word [edi+8],0
1674
        mov     byte [edi+12],0
1675
        mov     al,[value_size]
1676
        cmp     al,4
1677
        je      convert_fp_dword
1678
        cmp     al,8
1679
        je      convert_fp_qword
1680
        jmp     invalid_value
1681
      convert_fp_dword:
31 halyavin 1682
        xor     eax,eax
109 heavyiron 1683
        cmp     word [esi+8],8000h
1684
        je      fp_dword_store
1685
        mov     bx,[esi+8]
1686
        mov     eax,[esi+4]
1687
        shl     eax,1
1688
        shr     eax,9
1689
        jnc     fp_dword_ok
1690
        inc     eax
1691
        bt      eax,23
1692
        jnc     fp_dword_ok
1693
        and     eax,1 shl 23 - 1
1694
        inc     bx
1695
        shr     eax,1
1696
      fp_dword_ok:
31 halyavin 1697
        add     bx,7Fh
109 heavyiron 1698
        cmp     bx,100h
1699
        jae     value_out_of_range
1700
        shl     ebx,23
1701
        or      eax,ebx
1702
      fp_dword_store:
31 halyavin 1703
        mov     bl,[esi+11]
109 heavyiron 1704
        shl     ebx,31
1705
        or      eax,ebx
1706
        mov     [edi],eax
1707
        xor     eax,eax
1708
        mov     [edi+4],eax
1709
        add     esi,13
1710
        ret
1711
      convert_fp_qword:
31 halyavin 1712
        xor     eax,eax
109 heavyiron 1713
        xor     edx,edx
1714
        cmp     word [esi+8],8000h
1715
        je      fp_qword_store
1716
        mov     bx,[esi+8]
1717
        mov     eax,[esi]
1718
        mov     edx,[esi+4]
1719
        add     eax,eax
1720
        adc     edx,edx
1721
        mov     ecx,edx
1722
        shr     edx,12
1723
        shrd    eax,ecx,12
1724
        jnc     fp_qword_ok
1725
        add     eax,1
1726
        adc     edx,0
1727
        bt      edx,20
1728
        jnc     fp_qword_ok
1729
        and     edx,1 shl 20 - 1
1730
        inc     bx
1731
        shr     edx,1
1732
        rcr     eax,1
1733
      fp_qword_ok:
31 halyavin 1734
        add     bx,3FFh
109 heavyiron 1735
        cmp     bx,800h
1736
        jae     value_out_of_range
1737
        shl     ebx,20
1738
        or      edx,ebx
1739
      fp_qword_store:
31 halyavin 1740
        mov     bl,[esi+11]
109 heavyiron 1741
        shl     ebx,31
1742
        or      edx,ebx
1743
        mov     [edi],eax
1744
        mov     [edi+4],edx
1745
        add     esi,13
1746
        ret
1747
      get_string_value:
31 halyavin 1748
        inc     esi
109 heavyiron 1749
        lods    dword [esi]
1750
        mov     ecx,eax
1751
        cmp     ecx,8
1752
        ja      value_out_of_range
1753
        mov     edx,edi
1754
        xor     eax,eax
1755
        stos    dword [edi]
1756
        stos    dword [edi]
1757
        mov     edi,edx
1758
        rep     movs byte [edi],[esi]
1759
        mov     edi,edx
1760
        inc     esi
1761
        mov     word [edi+8],0
1762
        mov     byte [edi+12],0
1763
        ret
1764
31 halyavin 1765
 
1766
        mov     [value_size],1
109 heavyiron 1767
        mov     [size_override],-1
1768
        call    calculate_expression
1769
        mov     eax,[edi+16]
1770
        mov     [symbol_identifier],eax
1771
        mov     [value_type],0
1772
        cmp     word [edi+8],0
1773
        jne     invalid_value
1774
        cmp     byte [edi+12],0
1775
        je      check_byte_value
1776
        cmp     [error_line],0
1777
        jne     check_byte_value
1778
        mov     eax,[current_line]
1779
        mov     [error_line],eax
1780
        mov     [error],invalid_use_of_symbol
1781
      check_byte_value:
31 halyavin 1782
        mov     eax,[edi]
109 heavyiron 1783
        mov     edx,[edi+4]
1784
        or      edx,edx
1785
        jz      byte_positive
1786
        cmp     edx,-1
1787
        jne     range_exceeded
1788
        cmp     eax,-80h
1789
        jb      range_exceeded
1790
        ret
1791
      byte_positive:
31 halyavin 1792
        cmp     eax,100h
109 heavyiron 1793
        jae     range_exceeded
1794
      return_byte_value:
31 halyavin 1795
        ret
109 heavyiron 1796
      range_exceeded:
31 halyavin 1797
        xor     eax,eax
109 heavyiron 1798
        xor     edx,edx
1799
        cmp     [error_line],0
1800
        jne     return_byte_value
1801
        mov     ecx,[current_line]
1802
        mov     [error_line],ecx
1803
        mov     [error],value_out_of_range
1804
        ret
1805
get_word_value:
31 halyavin 1806
        mov     [value_size],2
109 heavyiron 1807
        mov     [size_override],-1
1808
        call    calculate_expression
1809
        mov     eax,[edi+16]
1810
        mov     [symbol_identifier],eax
1811
        cmp     word [edi+8],0
1812
        jne     invalid_value
1813
        mov     al,[edi+12]
1814
        mov     [value_type],al
1815
        cmp     al,2
1816
        jb      check_word_value
1817
        cmp     [error_line],0
1818
        jne     check_word_value
1819
        mov     eax,[current_line]
1820
        mov     [error_line],eax
1821
        mov     [error],invalid_use_of_symbol
1822
      check_word_value:
31 halyavin 1823
        mov     eax,[edi]
109 heavyiron 1824
        mov     edx,[edi+4]
1825
        or      edx,edx
1826
        jz      word_positive
1827
        cmp     edx,-1
1828
        jne     range_exceeded
1829
        cmp     eax,-8000h
1830
        jb      range_exceeded
1831
        ret
1832
      word_positive:
31 halyavin 1833
        cmp     eax,10000h
109 heavyiron 1834
        jae     range_exceeded
1835
        ret
1836
get_dword_value:
31 halyavin 1837
        mov     [value_size],4
109 heavyiron 1838
        mov     [size_override],-1
1839
        call    calculate_expression
1840
        mov     eax,[edi+16]
1841
        mov     [symbol_identifier],eax
1842
        cmp     word [edi+8],0
1843
        jne     invalid_value
1844
        mov     al,[edi+12]
1845
        mov     [value_type],al
1846
        cmp     al,4
1847
        jne     check_dword_value
1848
        mov     [value_type],2
1849
        mov     eax,[edi]
1850
        cdq
1851
        cmp     edx,[edi+4]
1852
        jne     range_exceeded
1853
        ret
1854
      check_dword_value:
31 halyavin 1855
        mov     eax,[edi]
109 heavyiron 1856
        mov     edx,[edi+4]
1857
        or      edx,edx
1858
        jz      dword_positive
1859
        cmp     edx,-1
1860
        jne     range_exceeded
1861
        bt      eax,31
1862
        jnc     range_exceeded
1863
      dword_positive:
31 halyavin 1864
        ret
109 heavyiron 1865
get_pword_value:
31 halyavin 1866
        mov     [value_size],6
109 heavyiron 1867
        mov     [size_override],-1
1868
        call    calculate_expression
1869
        mov     eax,[edi+16]
1870
        mov     [symbol_identifier],eax
1871
        cmp     word [edi+8],0
1872
        jne     invalid_value
1873
        mov     al,[edi+12]
1874
        mov     [value_type],al
1875
        cmp     al,4
1876
        jne     check_pword_value
1877
        cmp     [error_line],0
1878
        jne     check_pword_value
1879
        mov     eax,[current_line]
1880
        mov     [error_line],eax
1881
        mov     [error],invalid_use_of_symbol
1882
      check_pword_value:
31 halyavin 1883
        mov     eax,[edi]
109 heavyiron 1884
        mov     edx,[edi+4]
1885
        cmp     edx,10000h
1886
        jge     range_exceeded
1887
        cmp     edx,-8000h
1888
        jl      range_exceeded
1889
        ret
1890
get_qword_value:
31 halyavin 1891
        mov     [value_size],8
109 heavyiron 1892
        mov     [size_override],-1
1893
        call    calculate_expression
1894
        mov     eax,[edi+16]
1895
        mov     [symbol_identifier],eax
1896
        cmp     word [edi+8],0
1897
        jne     invalid_value
1898
        mov     al,[edi+12]
1899
        mov     [value_type],al
1900
      check_qword_value:
31 halyavin 1901
        mov     eax,[edi]
109 heavyiron 1902
        mov     edx,[edi+4]
1903
        ret
1904
get_value:
31 halyavin 1905
        mov     [operand_size],0
109 heavyiron 1906
        lods    byte [esi]
1907
        call    get_size_operator
1908
        cmp     al,'('
1909
        jne     invalid_value
1910
        mov     al,[operand_size]
1911
        cmp     al,1
1912
        je      value_byte
1913
        cmp     al,2
1914
        je      value_word
1915
        cmp     al,4
1916
        je      value_dword
1917
        cmp     al,6
1918
        je      value_pword
1919
        cmp     al,8
1920
        je      value_qword
1921
        or      al,al
1922
        jnz     invalid_value
1923
      value_qword:
31 halyavin 1924
        call    get_qword_value
109 heavyiron 1925
        ret
1926
      value_pword:
31 halyavin 1927
        call    get_pword_value
109 heavyiron 1928
        movzx   edx,dx
1929
        ret
1930
      value_dword:
31 halyavin 1931
        call    get_dword_value
109 heavyiron 1932
        xor     edx,edx
1933
        ret
1934
      value_word:
31 halyavin 1935
        call    get_word_value
109 heavyiron 1936
        xor     edx,edx
1937
        movzx   eax,ax
1938
        ret
1939
      value_byte:
31 halyavin 1940
        call    get_byte_value
109 heavyiron 1941
        xor     edx,edx
1942
        movzx   eax,al
1943
        ret
1944
get_address_value:
31 halyavin 1945
        mov     [address_size],0
109 heavyiron 1946
        mov     [value_size],8
1947
      calculate_address:
31 halyavin 1948
        cmp     byte [esi],'.'
109 heavyiron 1949
        je      invalid_address
1950
        call    calculate_expression
1951
        mov     eax,[edi+16]
1952
        mov     [address_symbol],eax
1953
        mov     al,[edi+12]
1954
        mov     [value_type],al
1955
        cmp     al,5
1956
        je      gotoff_address
1957
        test    al,1
1958
        jnz     invalid_use_of_symbol
1959
        or      al,al
1960
        jz      address_size_ok
1961
        shl     al,5
1962
        jmp     address_symbol_ok
1963
      gotoff_address:
1964
        mov     al,40h
1965
      address_symbol_ok:
31 halyavin 1966
        mov     ah,[address_size]
109 heavyiron 1967
        or      [address_size],al
1968
        shr     al,4
1969
        or      ah,ah
1970
        jz      address_size_ok
1971
        cmp     al,ah
1972
        je      address_size_ok
1973
        cmp     ax,0408h
1974
        jne     address_sizes_do_not_agree
1975
        mov     [value_type],2
1976
        mov     eax,[edi]
1977
        cdq
1978
        cmp     edx,[edi+4]
1979
        je      address_size_ok
1980
        cmp     [error_line],0
1981
        jne     address_size_ok
1982
        mov     ecx,[current_line]
1983
        mov     [error_line],ecx
1984
        mov     [error],value_out_of_range
1985
      address_size_ok:
1986
        xor     bx,bx
1987
        xor     cl,cl
1988
        mov     ch,[address_size]
1989
        cmp     word [edi+8],0
1990
        je      check_immediate_address
1991
        mov     al,[edi+8]
1992
        mov     dl,[edi+10]
1993
        call    get_address_register
1994
        mov     al,[edi+9]
1995
        mov     dl,[edi+11]
1996
        call    get_address_register
1997
        mov     ax,bx
1998
        shr     ah,4
1999
        shr     al,4
2000
        or      bh,bh
2001
        jz      check_address_registers
2002
        or      bl,bl
2003
        jz      check_address_registers
2004
        cmp     al,ah
2005
        jne     invalid_address
2006
      check_address_registers:
31 halyavin 2007
        or      al,ah
109 heavyiron 2008
        cmp     al,4
2009
        je      sib_allowed
2010
        cmp     al,8
2011
        je      sib_allowed
2012
        or      cl,cl
2013
        jz      check_word_value
2014
        cmp     cl,1
2015
        je      check_word_value
2016
        jmp     invalid_address
2017
      get_address_register:
31 halyavin 2018
        or      al,al
109 heavyiron 2019
        jz      address_register_ok
2020
        cmp     dl,1
2021
        jne     scaled_register
2022
        or      bh,bh
2023
        jnz     scaled_register
2024
        mov     bh,al
2025
      address_register_ok:
31 halyavin 2026
        ret
109 heavyiron 2027
      scaled_register:
31 halyavin 2028
        or      bl,bl
109 heavyiron 2029
        jnz     invalid_address
2030
        mov     bl,al
2031
        mov     cl,dl
2032
        jmp     address_register_ok
2033
      sib_allowed:
31 halyavin 2034
        or      bh,bh
109 heavyiron 2035
        jnz     check_index_scale
2036
        cmp     cl,2
2037
        je      special_index_scale
2038
        cmp     cl,3
2039
        je      special_index_scale
2040
        cmp     cl,5
2041
        je      special_index_scale
2042
        cmp     cl,9
2043
        je      special_index_scale
2044
      check_index_scale:
31 halyavin 2045
        or      cl,cl
109 heavyiron 2046
        jz      address_registers_ok
2047
        cmp     cl,1
2048
        je      address_registers_ok
2049
        cmp     cl,2
2050
        je      address_registers_ok
2051
        cmp     cl,4
2052
        je      address_registers_ok
2053
        cmp     cl,8
2054
        je      address_registers_ok
2055
        jmp     invalid_address
2056
      special_index_scale:
31 halyavin 2057
        mov     bh,bl
109 heavyiron 2058
        dec     cl
2059
      address_registers_ok:
31 halyavin 2060
        jmp     check_dword_value
109 heavyiron 2061
      check_immediate_address:
31 halyavin 2062
        cmp     [code_type],64
109 heavyiron 2063
        jne     check_dword_value
2064
        cmp     [address_size],4
2065
        je      check_dword_value
2066
        jmp     check_qword_value
2067
get_relative_offset:
31 halyavin 2068
        mov     [value_size],4
109 heavyiron 2069
        mov     [size_override],-1
2070
        call    calculate_expression
2071
      calculate_relative_offset:
31 halyavin 2072
        push    esi
109 heavyiron 2073
        add     edi,14h
2074
        mov     esi,[display_buffer]
2075
        sub     esi,7
2076
        lea     eax,[esi-14h]
2077
        cmp     eax,edi
2078
        jb      out_of_memory
2079
        mov     byte [esi],11h
2080
        xor     eax,eax
2081
        mov     dword [esi+1],eax
2082
        mov     word [esi+5],')' shl 8 + 81h
2083
        call    calculation_loop
2084
        pop     esi
2085
        cmp     word [edi+8],0
2086
        jne     invalid_value
2087
        mov     al,[edi+12]
2088
        mov     [value_type],al
2089
        mov     eax,[edi+16]
2090
        mov     [symbol_identifier],eax
2091
        mov     eax,[edi]
2092
        mov     edx,[edi+4]
2093
        or      edx,edx
2094
        jz      offset_positive
2095
        cmp     edx,-1
2096
        jne     range_exceeded
2097
        bt      eax,31
2098
        jnc     range_exceeded
2099
        ret
2100
      offset_positive:
31 halyavin 2101
        bt      eax,31
109 heavyiron 2102
        jc      range_exceeded
2103
        ret
2104
31 halyavin 2105
 
109 heavyiron 2106
        push    edi
2107
        call    preevaluate_logical_value
2108
      preevaluation_loop:
2109
        cmp     al,0FFh
2110
        je      invalid_logical_expression
2111
        mov     dl,[esi]
2112
        inc     esi
2113
        cmp     dl,'|'
2114
        je      preevaluate_or
2115
        cmp     dl,'&'
2116
        je      preevaluate_and
2117
        cmp     dl,'}'
2118
        je      preevaluation_done
2119
        or      dl,dl
2120
        jnz     invalid_logical_expression
2121
      preevaluation_done:
2122
        pop     edx
2123
        dec     esi
2124
        ret
2125
      preevaluate_or:
2126
        cmp     al,'1'
2127
        je      quick_true
2128
        cmp     al,'0'
2129
        je      leave_only_following
2130
        push    edi
2131
        mov     al,dl
2132
        stos    byte [edi]
2133
        call    preevaluate_logical_value
2134
        pop     ebx
2135
        cmp     al,'0'
2136
        je      leave_only_preceding
2137
        cmp     al,'1'
2138
        jne     preevaluation_loop
2139
        stos    byte [edi]
2140
        xor     al,al
2141
        jmp     preevaluation_loop
2142
      preevaluate_and:
2143
        cmp     al,'0'
2144
        je      quick_false
2145
        cmp     al,'1'
2146
        je      leave_only_following
2147
        push    edi
2148
        mov     al,dl
2149
        stos    byte [edi]
2150
        call    preevaluate_logical_value
2151
        pop     ebx
2152
        cmp     al,'1'
2153
        je      leave_only_preceding
2154
        cmp     al,'0'
2155
        jne     preevaluation_loop
2156
        stos    byte [edi]
2157
        xor     al,al
2158
        jmp     preevaluation_loop
2159
      leave_only_following:
2160
        mov     edi,[esp]
2161
        call    preevaluate_logical_value
2162
        jmp     preevaluation_loop
2163
      leave_only_preceding:
2164
        mov     edi,ebx
2165
        xor     al,al
2166
        jmp     preevaluation_loop
2167
      quick_true:
2168
        call    skip_logical_value
2169
        jc      invalid_logical_expression
2170
        mov     edi,[esp]
2171
        mov     al,'1'
2172
        jmp     preevaluation_loop
2173
      quick_false:
2174
        call    skip_logical_value
2175
        jc      invalid_logical_expression
2176
        mov     edi,[esp]
2177
        mov     al,'0'
2178
        jmp     preevaluation_loop
2179
      invalid_logical_expression:
2180
        pop     edi
2181
        mov     esi,edi
2182
        mov     al,0FFh
2183
        stos    byte [edi]
2184
        ret
2185
skip_logical_value:
2186
        cmp     byte [esi],'~'
2187
        jne     negation_skipped
2188
        inc     esi
2189
        jmp     skip_logical_value
2190
      negation_skipped:
2191
        cmp     byte [esi],'{'
2192
        jne     skip_simple_logical_value
2193
        inc     esi
2194
      skip_logical_expression:
2195
        call    skip_logical_value
2196
        lods    byte [esi]
2197
        or      al,al
2198
        jz      wrongly_structured_logical_expression
2199
        cmp     al,0Fh
2200
        je      wrongly_structured_logical_expression
2201
        cmp     al,'|'
2202
        je      skip_logical_expression
2203
        cmp     al,'&'
2204
        je      skip_logical_expression
2205
        cmp     al,'}'
2206
        je      logical_value_skipped
2207
      wrongly_structured_logical_expression:
2208
        stc
2209
        ret
2210
      skip_simple_logical_value:
2211
        mov     al,[esi]
2212
        or      al,al
2213
        jz      logical_value_skipped
2214
        cmp     al,0Fh
2215
        je      logical_value_skipped
2216
        cmp     al,'}'
2217
        je      logical_value_skipped
2218
        cmp     al,'|'
2219
        je      logical_value_skipped
2220
        cmp     al,'&'
2221
        je      logical_value_skipped
2222
        call    skip_symbol
2223
        jmp     skip_simple_logical_value
2224
      logical_value_skipped:
2225
        clc
2226
        ret
2227
31 halyavin 2228
 
109 heavyiron 2229
        mov     ebp,edi
2230
      preevaluate_negation:
2231
        cmp     byte [esi],'~'
2232
        jne     preevaluate_negation_ok
2233
        movs    byte [edi],[esi]
2234
        jmp     preevaluate_negation
2235
      preevaluate_negation_ok:
2236
        mov     ebx,esi
2237
        xor     edx,edx
2238
        cmp     byte [esi],'{'
2239
        jne     find_logical_value_boundaries
2240
        movs    byte [edi],[esi]
2241
        push    ebp
2242
        call    preevaluate_logical_expression
2243
        pop     ebp
2244
        cmp     al,0FFh
2245
        je      invalid_logical_value
2246
        cmp     byte [esi],'}'
2247
        jne     invalid_logical_value
2248
        or      al,al
2249
        jnz     preevaluated_expression_value
2250
        movs    byte [edi],[esi]
2251
        ret
2252
      preevaluated_expression_value:
2253
        inc     esi
2254
        lea     edx,[edi-1]
2255
        sub     edx,ebp
2256
        test    edx,1
2257
        jz      expression_negation_ok
2258
        xor     al,1
2259
      expression_negation_ok:
2260
        mov     edi,ebp
2261
        ret
2262
      invalid_logical_value:
2263
        mov     edi,ebp
2264
        mov     al,0FFh
2265
        ret
2266
      find_logical_value_boundaries:
2267
        mov     al,[esi]
2268
        or      al,al
2269
        jz      logical_value_boundaries_found
2270
        cmp     al,'}'
2271
        je      logical_value_boundaries_found
2272
        cmp     al,'|'
2273
        je      logical_value_boundaries_found
2274
        cmp     al,'&'
2275
        je      logical_value_boundaries_found
2276
        or      edx,edx
2277
        jnz     next_symbol_in_logical_value
2278
        cmp     al,0F0h
2279
        je      preevaluable_logical_operator
2280
        cmp     al,0F7h
2281
        je      preevaluable_logical_operator
2282
        cmp     al,0F6h
2283
        jne     next_symbol_in_logical_value
2284
      preevaluable_logical_operator:
2285
        mov     edx,esi
2286
      next_symbol_in_logical_value:
2287
        call    skip_symbol
2288
        jmp     find_logical_value_boundaries
2289
      logical_value_boundaries_found:
2290
        or      edx,edx
2291
        jz      non_preevaluable_logical_value
2292
        mov     al,[edx]
2293
        cmp     al,0F0h
2294
        je      compare_symbols
2295
        cmp     al,0F7h
2296
        je      compare_symbol_types
2297
        cmp     al,0F6h
2298
        je      scan_symbols_list
2299
      non_preevaluable_logical_value:
2300
        mov     ecx,esi
2301
        mov     esi,ebx
2302
        sub     ecx,esi
2303
        jz      invalid_logical_value
2304
        cmp     esi,edi
2305
        je      leave_logical_value_intact
2306
        rep     movs byte [edi],[esi]
2307
        xor     al,al
2308
        ret
2309
      leave_logical_value_intact:
2310
        add     edi,ecx
2311
        add     esi,ecx
2312
        xor     al,al
2313
        ret
2314
      compare_symbols:
31 halyavin 2315
        lea     ecx,[esi-1]
109 heavyiron 2316
        sub     ecx,edx
2317
        mov     eax,edx
2318
        sub     eax,ebx
2319
        cmp     ecx,eax
2320
        jne     preevaluated_false
2321
        push    esi edi
2322
        mov     esi,ebx
2323
        lea     edi,[edx+1]
2324
        repe    cmps byte [esi],[edi]
2325
        pop     edi esi
2326
        je      preevaluated_true
2327
      preevaluated_false:
2328
        mov     eax,edi
2329
        sub     eax,ebp
2330
        test    eax,1
2331
        jnz     store_true
2332
      store_false:
2333
        mov     edi,ebp
2334
        mov     al,'0'
2335
        ret
2336
      preevaluated_true:
2337
        mov     eax,edi
2338
        sub     eax,ebp
2339
        test    eax,1
2340
        jnz     store_false
2341
      store_true:
2342
        mov     edi,ebp
2343
        mov     al,'1'
2344
        ret
2345
      compare_symbol_types:
31 halyavin 2346
        push    esi
109 heavyiron 2347
        lea     esi,[edx+1]
2348
      type_comparison:
2349
        cmp     esi,[esp]
2350
        je      types_compared
2351
        mov     al,[esi]
2352
        cmp     al,[ebx]
2353
        jne     different_type
2354
        cmp     al,'('
2355
        jne     equal_type
2356
        mov     al,[esi+1]
2357
        mov     ah,[ebx+1]
2358
        cmp     al,ah
2359
        je      equal_type
2360
        or      al,al
2361
        jz      different_type
2362
        or      ah,ah
2363
        jz      different_type
2364
        cmp     al,'.'
2365
        je      different_type
2366
        cmp     ah,'.'
2367
        je      different_type
2368
      equal_type:
31 halyavin 2369
        call    skip_symbol
109 heavyiron 2370
        xchg    esi,ebx
2371
        call    skip_symbol
2372
        xchg    esi,ebx
2373
        jmp     type_comparison
2374
      types_compared:
31 halyavin 2375
        pop     esi
109 heavyiron 2376
        cmp     byte [ebx],0F7h
2377
        jne     preevaluated_false
2378
        jmp     preevaluated_true
2379
      different_type:
2380
        pop     esi
2381
        jmp     preevaluated_false
2382
      scan_symbols_list:
31 halyavin 2383
        push    edi esi
109 heavyiron 2384
        lea     esi,[edx+1]
2385
        sub     edx,ebx
2386
        lods    byte [esi]
2387
        cmp     al,'<'
2388
        jne     invalid_symbols_list
2389
      get_next_from_list:
2390
        mov     edi,esi
2391
      get_from_list:
2392
        cmp     byte [esi],','
2393
        je      compare_in_list
2394
        cmp     byte [esi],'>'
2395
        je      compare_in_list
2396
        cmp     esi,[esp]
2397
        jae     invalid_symbols_list
2398
        call    skip_symbol
2399
        jmp     get_from_list
2400
      compare_in_list:
31 halyavin 2401
        mov     ecx,esi
109 heavyiron 2402
        sub     ecx,edi
2403
        cmp     ecx,edx
2404
        jne     not_equal_length_in_list
2405
        mov     esi,ebx
2406
        repe    cmps byte [esi],[edi]
2407
        mov     esi,edi
2408
        jne     not_equal_in_list
2409
      skip_rest_of_list:
31 halyavin 2410
        cmp     byte [esi],'>'
109 heavyiron 2411
        je      check_list_end
2412
        cmp     esi,[esp]
2413
        jae     invalid_symbols_list
2414
        call    skip_symbol
2415
        jmp     skip_rest_of_list
2416
      check_list_end:
2417
        inc     esi
2418
        cmp     esi,[esp]
2419
        jne     invalid_symbols_list
2420
        pop     esi edi
2421
        jmp     preevaluated_true
2422
      not_equal_in_list:
31 halyavin 2423
        add     esi,ecx
109 heavyiron 2424
      not_equal_length_in_list:
2425
        lods    byte [esi]
2426
        cmp     al,','
2427
        je      get_next_from_list
2428
        cmp     esi,[esp]
2429
        jne     invalid_symbols_list
2430
        pop     esi edi
2431
        jmp     preevaluated_false
2432
      invalid_symbols_list:
2433
        pop     esi edi
2434
        jmp     invalid_logical_value
2435
2436
 
2437
        call    get_logical_value
2438
      logical_loop:
2439
        cmp     byte [esi],'|'
2440
        je      logical_or
2441
        cmp     byte [esi],'&'
2442
        je      logical_and
2443
        ret
2444
      logical_or:
2445
        inc     esi
2446
        or      al,al
2447
        jnz     logical_value_already_determined
2448
        push    eax
2449
        call    get_logical_value
2450
        pop     ebx
2451
        or      al,bl
2452
        jmp     logical_loop
2453
      logical_and:
2454
        inc     esi
2455
        or      al,al
2456
        jz      logical_value_already_determined
2457
        push    eax
2458
        call    get_logical_value
2459
        pop     ebx
2460
        and     al,bl
2461
        jmp     logical_loop
2462
      logical_value_already_determined:
2463
        push    eax
2464
        call    skip_logical_value
2465
        jc      invalid_expression
2466
        pop     eax
2467
        jmp     logical_loop
2468
get_logical_value:
2469
        xor     al,al
2470
      check_for_negation:
2471
        cmp     byte [esi],'~'
2472
        jne     negation_ok
2473
        inc     esi
2474
        xor     al,-1
2475
        jmp     check_for_negation
2476
      negation_ok:
2477
        push    eax
2478
        mov     al,[esi]
2479
        cmp     al,'{'
2480
        je      logical_expression
2481
        cmp     al,0FFh
2482
        je      invalid_expression
2483
        cmp     al,88h
2484
        je      check_for_defined
2485
        cmp     al,89h
2486
        je      check_for_used
2487
        cmp     al,'0'
2488
        je      given_false
2489
        cmp     al,'1'
2490
        je      given_true
2491
        call    get_value
2492
        mov     bl,[value_type]
2493
        push    eax edx ebx
2494
        mov     al,[esi]
2495
        or      al,al
2496
        jz      logical_number
2497
        cmp     al,0Fh
2498
        je      logical_number
2499
        cmp     al,'}'
2500
        je      logical_number
2501
        cmp     al,'&'
2502
        je      logical_number
2503
        cmp     al,'|'
2504
        je      logical_number
2505
        inc     esi
2506
        mov     [compare_type],al
2507
        call    get_value
2508
        pop     ebx
2509
        cmp     [next_pass_needed],0
2510
        jne     values_ok
2511
        cmp     bl,[value_type]
2512
        jne     invalid_use_of_symbol
2513
      values_ok:
31 halyavin 2514
        pop     ecx ebx
109 heavyiron 2515
        cmp     [compare_type],'='
2516
        je      check_equal
2517
        cmp     [compare_type],'>'
2518
        je      check_greater
2519
        cmp     [compare_type],'<'
2520
        je      check_less
2521
        cmp     [compare_type],0F1h
2522
        je      check_not_equal
2523
        cmp     [compare_type],0F2h
2524
        je      check_not_less
2525
        cmp     [compare_type],0F3h
2526
        je      check_not_greater
2527
        jmp     invalid_expression
2528
      check_equal:
31 halyavin 2529
        cmp     eax,ebx
109 heavyiron 2530
        jne     return_false
2531
        cmp     edx,ecx
2532
        jne     return_false
2533
        jmp     return_true
2534
      check_greater:
31 halyavin 2535
        cmp     edx,ecx
109 heavyiron 2536
        jl      return_true
2537
        jg      return_false
2538
        cmp     eax,ebx
2539
        jb      return_true
2540
        jae     return_false
2541
      check_less:
31 halyavin 2542
        cmp     edx,ecx
109 heavyiron 2543
        jl      return_false
2544
        jg      return_true
2545
        cmp     eax,ebx
2546
        jbe     return_false
2547
        ja      return_true
2548
      check_not_less:
31 halyavin 2549
        cmp     edx,ecx
109 heavyiron 2550
        jl      return_true
2551
        jg      return_false
2552
        cmp     eax,ebx
2553
        jbe     return_true
2554
        ja      return_false
2555
      check_not_greater:
31 halyavin 2556
        cmp     edx,ecx
109 heavyiron 2557
        jl      return_false
2558
        jg      return_true
2559
        cmp     eax,ebx
2560
        jb      return_false
2561
        jae     return_true
2562
      check_not_equal:
31 halyavin 2563
        cmp     eax,ebx
109 heavyiron 2564
        jne     return_true
2565
        cmp     edx,ecx
2566
        jne     return_true
2567
        jmp     return_false
2568
      logical_number:
31 halyavin 2569
        pop     ebx edx eax
109 heavyiron 2570
        or      bl,bl
2571
        jnz     invalid_expression
2572
        or      eax,edx
2573
        jnz     return_true
2574
        jmp     return_false
2575
      check_for_defined:
31 halyavin 2576
        or      bl,-1
109 heavyiron 2577
        lods    word [esi]
2578
        cmp     ah,'('
2579
        jne     invalid_expression
2580
      check_expression:
31 halyavin 2581
        lods    byte [esi]
109 heavyiron 2582
        or      al,al
2583
        jz      defined_string
2584
        cmp     al,'.'
2585
        je      defined_fp_value
2586
        cmp     al,')'
2587
        je      expression_checked
2588
        cmp     al,0Fh
2589
        je      check_expression
2590
        cmp     al,10h
2591
        je      defined_register
2592
        cmp     al,11h
2593
        je      check_if_symbol_defined
2594
        cmp     al,80h
2595
        jae     check_expression
2596
        movzx   eax,al
2597
        add     esi,eax
2598
        jmp     check_expression
2599
      defined_register:
31 halyavin 2600
        inc     esi
109 heavyiron 2601
        jmp     check_expression
2602
      defined_fp_value:
31 halyavin 2603
        add     esi,12
109 heavyiron 2604
        jmp     expression_checked
2605
      defined_string:
31 halyavin 2606
        lods    dword [esi]
109 heavyiron 2607
        add     esi,eax
2608
        inc     esi
2609
        jmp     expression_checked
2610
      check_if_symbol_defined:
31 halyavin 2611
        lods    dword [esi]
109 heavyiron 2612
        cmp     eax,-1
2613
        je      invalid_expression
2614
        cmp     eax,0Fh
2615
        jb      check_expression
2616
        je      reserved_word_used_as_symbol
2617
        test    byte [eax+8],4
2618
        jnz     no_prediction
2619
        test    byte [eax+8],1
2620
        jz      symbol_predicted_undefined
2621
        mov     cx,[current_pass]
2622
        sub     cx,[eax+16]
2623
        jz      check_expression
2624
        cmp     cx,1
2625
        ja      symbol_predicted_undefined
2626
        or      byte [eax+8],40h+80h
2627
        jmp     check_expression
2628
      no_prediction:
31 halyavin 2629
        test    byte [eax+8],1
109 heavyiron 2630
        jz      symbol_undefined
2631
        mov     cx,[current_pass]
2632
        sub     cx,[eax+16]
2633
        jz      check_expression
2634
        jmp     symbol_undefined
2635
      symbol_predicted_undefined:
31 halyavin 2636
        or      byte [eax+8],40h
109 heavyiron 2637
        and     byte [eax+8],not 80h
2638
      symbol_undefined:
31 halyavin 2639
        xor     bl,bl
109 heavyiron 2640
        jmp     check_expression
2641
      expression_checked:
31 halyavin 2642
        mov     al,bl
109 heavyiron 2643
        jmp     logical_value_ok
2644
      check_for_used:
31 halyavin 2645
        lods    word [esi]
109 heavyiron 2646
        cmp     ah,2
2647
        jne     invalid_expression
2648
        lods    dword [esi]
2649
        cmp     eax,0Fh
2650
        jb      invalid_use_of_symbol
2651
        je      reserved_word_used_as_symbol
2652
        inc     esi
2653
        test    byte [eax+8],8
2654
        jz      not_used
2655
        mov     cx,[current_pass]
2656
        sub     cx,[eax+18]
2657
        jz      return_true
2658
        cmp     cx,1
2659
        ja      not_used
2660
        or      byte [eax+8],10h+20h
2661
        jmp     return_true
2662
      not_used:
31 halyavin 2663
        or      byte [eax+8],10h
109 heavyiron 2664
        and     byte [eax+8],not 20h
2665
        jmp     return_false
2666
      given_false:
2667
        inc     esi
2668
      return_false:
31 halyavin 2669
        xor     al,al
109 heavyiron 2670
        jmp     logical_value_ok
2671
      given_true:
2672
        inc     esi
2673
      return_true:
31 halyavin 2674
        or      al,-1
109 heavyiron 2675
        jmp     logical_value_ok
2676
      logical_expression:
31 halyavin 2677
        inc     esi
109 heavyiron 2678
        call    calculate_logical_expression
2679
        push    eax
2680
        lods    byte [esi]
2681
        cmp     al,'}'
2682
        jne     invalid_expression
2683
        pop     eax
2684
      logical_value_ok:
31 halyavin 2685
        pop     ebx
109 heavyiron 2686
        xor     al,bl
2687
        ret
2688
>