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
        mov     eax,[memory_end]
109 heavyiron 7
        mov     [labels_list],eax
8
        mov     eax,[additional_memory]
9
        mov     [free_additional_memory],eax
10
        xor     eax,eax
11
        mov     [current_locals_prefix],eax
12
        mov     [anonymous_reverse],eax
13
        mov     [anonymous_forward],eax
14
        mov     [hash_tree],eax
15
        mov     [blocks_stack],eax
16
        mov     esi,[memory_start]
17
        mov     edi,[source_start]
18
      parser_loop:
31 halyavin 19
        mov     [current_line],esi
109 heavyiron 20
        lea     eax,[edi+100h]
21
        cmp     eax,[labels_list]
22
        jae     out_of_memory
23
        cmp     byte [esi+16],0
24
        je      empty_line
25
        mov     al,0Fh
26
        stos    byte [edi]
27
        mov     eax,esi
28
        stos    dword [edi]
29
        add     esi,16
30
      parse_line:
31
        cmp     byte [esi],1Ah
32
        jne     empty_instruction
33
        push    edi
34
        add     esi,2
35
        movzx   ecx,byte [esi-1]
36
        cmp     byte [esi+ecx],':'
37
        je      simple_label
38
        cmp     byte [esi+ecx],'='
39
        je      constant_label
40
        call    get_instruction
41
        jnc     main_instruction_identified
42
        cmp     byte [esi+ecx],1Ah
43
        jne     no_data_label
44
        push    esi ecx
45
        lea     esi,[esi+ecx+2]
46
        movzx   ecx,byte [esi-1]
47
        call    get_data_directive
48
        jnc     data_label
49
        pop     ecx esi
50
      no_data_label:
51
        call    get_data_directive
52
        jnc     main_instruction_identified
53
        pop     edi
54
        sub     esi,2
55
        xor     bx,bx
56
        call    parse_line_contents
57
        jmp     parse_next_line
58
      simple_label:
59
        pop     edi
60
        call    identify_label
61
        mov     byte [edi],2
62
        inc     edi
63
        stos    dword [edi]
64
        inc     esi
65
        xor     al,al
66
        stos    byte [edi]
67
        jmp     parse_line
68
      constant_label:
69
        pop     edi
70
        call    get_label_id
71
        mov     byte [edi],3
72
        inc     edi
73
        stos    dword [edi]
74
        xor     al,al
75
        stos    byte [edi]
76
        inc     esi
77
        xor     bx,bx
78
        call    parse_line_contents
79
        jmp     parse_next_line
80
      data_label:
81
        pop     ecx edx
82
        pop     edi
83
        push    eax ebx esi
84
        mov     esi,edx
85
        movzx   ecx,byte [esi-1]
86
        call    identify_label
87
        mov     byte [edi],2
88
        inc     edi
89
        stos    dword [edi]
90
        pop     esi ebx eax
91
        stos    byte [edi]
92
        push    edi
93
      main_instruction_identified:
94
        pop     edi
95
        mov     dl,al
96
        mov     al,1
97
        stos    byte [edi]
98
        mov     ax,bx
99
        stos    word [edi]
100
        mov     al,dl
101
        stos    byte [edi]
102
        cmp     bx,if_directive-assembler
103
        je      parse_block
104
        cmp     bx,repeat_directive-assembler
105
        je      parse_block
106
        cmp     bx,while_directive-assembler
107
        je      parse_block
108
        cmp     bx,end_directive-assembler
109
        je      parse_end_directive
110
        cmp     bx,else_directive-assembler
111
        je      parse_else
112
      common_parse:
113
        call    parse_line_contents
114
        jmp     parse_next_line
115
      empty_instruction:
116
        lods    byte [esi]
117
        or      al,al
118
        jz      parse_next_line
119
        cmp     al,':'
120
        je      invalid_name
121
        cmp     al,3Bh
122
        je      skip_preprocessed_symbol
123
        dec     esi
124
        call    parse_argument
125
        jmp     parse_next_line
126
      skip_preprocessed_symbol:
127
        lods    byte [esi]
128
        movzx   eax,al
129
        add     esi,eax
130
      skip_next:
131
        lods    byte [esi]
132
        or      al,al
133
        jz      parse_next_line
134
        cmp     al,1Ah
135
        je      skip_preprocessed_symbol
136
        cmp     al,3Bh
137
        je      skip_preprocessed_symbol
138
        cmp     al,22h
139
        je      skip_preprocessed_string
140
        jmp     skip_next
141
      skip_preprocessed_string:
142
        lods    dword [esi]
143
        add     esi,eax
144
        jmp     skip_next
145
      empty_line:
146
        add     esi,17
147
      parse_next_line:
31 halyavin 148
        cmp     esi,[source_start]
109 heavyiron 149
        jb      parser_loop
150
      source_parsed:
151
        cmp     [blocks_stack],0
152
        je      blocks_stack_ok
153
        pop     eax
154
        pop     [current_line]
155
        jmp     missing_end_directive
156
      blocks_stack_ok:
157
        xor     al,al
158
        stos    byte [edi]
159
        mov     eax,[error_line]
160
        mov     [current_line],eax
161
        cmp     [anonymous_forward],0
162
        jne     invalid_value
163
        add     edi,0Fh
164
        and     edi,not 0Fh
165
        mov     [code_start],edi
166
        ret
167
      parse_block:
168
        mov     eax,esp
169
        sub     eax,100h
170
        jc      stack_overflow
171
        cmp     eax,[stack_limit]
172
        jb      stack_overflow
173
        push    [current_line]
174
        mov     ax,bx
175
        shl     eax,16
176
        push    eax
177
        inc     [blocks_stack]
178
        cmp     bx,if_directive-assembler
179
        je      parse_if
180
        cmp     bx,while_directive-assembler
181
        je      parse_while
182
        call    parse_line_contents
183
        jmp     parse_next_line
184
      parse_end_directive:
185
        cmp     byte [esi],1Ah
186
        jne     common_parse
187
        push    edi
188
        inc     esi
189
        movzx   ecx,byte [esi]
190
        inc     esi
191
        call    get_instruction
192
        pop     edi
193
        jnc     parse_end_block
194
        sub     esi,2
195
        jmp     common_parse
196
      parse_end_block:
197
        mov     dl,al
198
        mov     al,1
199
        stos    byte [edi]
200
        mov     ax,bx
201
        stos    word [edi]
202
        mov     al,dl
203
        stos    byte [edi]
204
        lods    byte [esi]
205
        or      al,al
206
        jnz     extra_characters_on_line
207
        cmp     bx,if_directive-assembler
208
        je      close_parsing_block
209
        cmp     bx,repeat_directive-assembler
210
        je      close_parsing_block
211
        cmp     bx,while_directive-assembler
212
        je      close_parsing_block
213
        jmp     parse_next_line
214
      close_parsing_block:
215
        cmp     [blocks_stack],0
216
        je      unexpected_instruction
217
        cmp     bx,[esp+2]
218
        jne     unexpected_instruction
219
        dec     [blocks_stack]
220
        pop     eax edx
221
        cmp     bx,if_directive-assembler
222
        jne     parse_next_line
223
        test    al,1100b
224
        jz      parse_next_line
225
        test    al,10000b
226
        jnz     parse_next_line
227
        sub     edi,8
228
        jmp     parse_next_line
229
      parse_if:
230
        push    edi
231
        call    parse_line_contents
232
        xor     al,al
233
        stos    byte [edi]
234
        xchg    esi,[esp]
235
        mov     edi,esi
236
        call    preevaluate_logical_expression
237
        pop     esi
238
        cmp     al,'0'
239
        je      parse_false_condition_block
240
        cmp     al,'1'
241
        je      parse_true_condition_block
242
        or      byte [esp],10000b
243
        jmp     parse_next_line
244
      parse_while:
245
        push    edi
246
        call    parse_line_contents
247
        xor     al,al
248
        stos    byte [edi]
249
        xchg    esi,[esp]
250
        mov     edi,esi
251
        call    preevaluate_logical_expression
252
        pop     esi
253
        cmp     al,'0'
254
        je      parse_false_condition_block
255
        cmp     al,'1'
256
        jne     parse_next_line
257
        stos    byte [edi]
258
        jmp     parse_next_line
259
      parse_false_condition_block:
260
        or      byte [esp],1
261
        sub     edi,4
262
        jmp     skip_parsing
263
      parse_true_condition_block:
264
        or      byte [esp],100b
265
        sub     edi,4
266
        jmp     parse_next_line
267
      parse_else:
268
        cmp     [blocks_stack],0
269
        je      unexpected_instruction
270
        cmp     word [esp+2],if_directive-assembler
271
        jne     unexpected_instruction
272
        lods    byte [esi]
273
        or      al,al
274
        jz      parse_pure_else
275
        cmp     al,1Ah
276
        jne     extra_characters_on_line
277
        push    edi
278
        movzx   ecx,byte [esi]
279
        inc     esi
280
        call    get_instruction
281
        jc      extra_characters_on_line
282
        pop     edi
283
        cmp     bx,if_directive-assembler
284
        jne     extra_characters_on_line
285
        test    byte [esp],100b
286
        jnz     skip_true_condition_else
287
        mov     dl,al
288
        mov     al,1
289
        stos    byte [edi]
290
        mov     ax,bx
291
        stos    word [edi]
292
        mov     al,dl
293
        stos    byte [edi]
294
        jmp     parse_if
295
      skip_true_condition_else:
296
        sub     edi,4
297
        or      byte [esp],1
298
        jmp     skip_parsing_contents
299
      parse_pure_else:
300
        bts     dword [esp],1
301
        jc      unexpected_instruction
302
        test    byte [esp],100b
303
        jz      parse_next_line
304
        sub     edi,4
305
        or      byte [esp],1
306
        jmp     skip_parsing
307
      skip_parsing:
308
        cmp     esi,[source_start]
309
        jae     source_parsed
310
        mov     [current_line],esi
311
        add     esi,16
312
      skip_parsing_line:
313
        cmp     byte [esi],1Ah
314
        jne     skip_parsing_contents
315
        inc     esi
316
        movzx   ecx,byte [esi]
317
        inc     esi
318
        cmp     byte [esi+ecx],':'
319
        je      skip_parsing_label
320
        push    edi
321
        call    get_instruction
322
        pop     edi
323
        jnc     skip_parsing_instruction
324
        add     esi,ecx
325
        jmp     skip_parsing_contents
326
      skip_parsing_label:
327
        lea     esi,[esi+ecx+1]
328
        jmp     skip_parsing_line
329
      skip_parsing_instruction:
330
        cmp     bx,if_directive-assembler
331
        je      skip_parsing_block
332
        cmp     bx,repeat_directive-assembler
333
        je      skip_parsing_block
334
        cmp     bx,while_directive-assembler
335
        je      skip_parsing_block
336
        cmp     bx,end_directive-assembler
337
        je      skip_parsing_end_directive
338
        cmp     bx,else_directive-assembler
339
        je      skip_parsing_else
340
      skip_parsing_contents:
341
        lods    byte [esi]
342
        or      al,al
343
        jz      skip_parsing
344
        cmp     al,1Ah
345
        je      skip_parsing_symbol
346
        cmp     al,3Bh
347
        je      skip_parsing_symbol
348
        cmp     al,22h
349
        je      skip_parsing_string
350
        jmp     skip_parsing_contents
351
      skip_parsing_symbol:
352
        lods    byte [esi]
353
        movzx   eax,al
354
        add     esi,eax
355
        jmp     skip_parsing_contents
356
      skip_parsing_string:
357
        lods    dword [esi]
358
        add     esi,eax
359
        jmp     skip_parsing_contents
360
      skip_parsing_block:
361
        mov     eax,esp
362
        sub     eax,100h
363
        jc      stack_overflow
364
        cmp     eax,[stack_limit]
365
        jb      stack_overflow
366
        push    [current_line]
367
        mov     ax,bx
368
        shl     eax,16
369
        push    eax
370
        inc     [blocks_stack]
371
        jmp     skip_parsing_contents
372
      skip_parsing_end_directive:
373
        cmp     byte [esi],1Ah
374
        jne     skip_parsing_contents
375
        push    edi
376
        inc     esi
377
        movzx   ecx,byte [esi]
378
        inc     esi
379
        call    get_instruction
380
        pop     edi
381
        jnc     skip_parsing_end_block
382
        add     esi,ecx
383
        jmp     skip_parsing_contents
384
      skip_parsing_end_block:
385
        lods    byte [esi]
386
        or      al,al
387
        jnz     extra_characters_on_line
388
        cmp     bx,if_directive-assembler
389
        je      close_skip_parsing_block
390
        cmp     bx,repeat_directive-assembler
391
        je      close_skip_parsing_block
392
        cmp     bx,while_directive-assembler
393
        je      close_skip_parsing_block
394
        jmp     skip_parsing
395
      close_skip_parsing_block:
396
        cmp     [blocks_stack],0
397
        je      unexpected_instruction
398
        cmp     bx,[esp+2]
399
        jne     unexpected_instruction
400
        dec     [blocks_stack]
401
        pop     eax edx
402
        test    al,1
403
        jz      skip_parsing
404
        cmp     bx,if_directive-assembler
405
        jne     parse_next_line
406
        test    al,10000b
407
        jz      parse_next_line
408
        mov     al,0Fh
409
        stos    byte [edi]
410
        mov     eax,[current_line]
411
        stos    dword [edi]
412
        mov     eax,1 + (end_directive-assembler) shl 8
413
        stos    dword [edi]
414
        mov     eax,1 + (if_directive-assembler) shl 8
415
        stos    dword [edi]
416
        jmp     parse_next_line
417
      skip_parsing_else:
418
        cmp     [blocks_stack],0
419
        je      unexpected_instruction
420
        cmp     word [esp+2],if_directive-assembler
421
        jne     unexpected_instruction
422
        lods    byte [esi]
423
        or      al,al
424
        jz      skip_parsing_pure_else
425
        cmp     al,1Ah
426
        jne     extra_characters_on_line
427
        push    edi
428
        movzx   ecx,byte [esi]
429
        inc     esi
430
        call    get_instruction
431
        jc      extra_characters_on_line
432
        pop     edi
433
        cmp     bx,if_directive-assembler
434
        jne     extra_characters_on_line
435
        mov     al,[esp]
436
        test    al,1
437
        jz      skip_parsing_contents
438
        test    al,100b
439
        jnz     skip_parsing_contents
440
        test    al,10000b
441
        jnz     parse_else_if
442
        xor     al,al
443
        mov     [esp],al
444
        mov     al,0Fh
445
        stos    byte [edi]
446
        mov     eax,[current_line]
447
        stos    dword [edi]
448
      parse_else_if:
449
        mov     eax,1 + (if_directive-assembler) shl 8
450
        stos    dword [edi]
451
        jmp     parse_if
452
      skip_parsing_pure_else:
453
        bts     dword [esp],1
454
        jc      unexpected_instruction
455
        mov     al,[esp]
456
        test    al,1
457
        jz      skip_parsing
458
        test    al,100b
459
        jnz     skip_parsing
460
        and     al,not 1
461
        or      al,1000b
462
        mov     [esp],al
463
        jmp     parse_next_line
464
31 halyavin 465
 
109 heavyiron 466
        mov     [parenthesis_stack],0
467
      parse_instruction_arguments:
468
        cmp     bx,prefix_instruction-assembler
469
        je      allow_embedded_instruction
470
        cmp     bx,times_directive-assembler
471
        je      parse_times_directive
472
        cmp     bx,end_directive-assembler
473
        je      allow_embedded_instruction
474
        cmp     bx,label_directive-assembler
475
        je      parse_label_directive
476
        cmp     bx,segment_directive-assembler
477
        je      parse_label_directive
478
        cmp     bx,load_directive-assembler
479
        je      parse_load_directive
480
        cmp     bx,extrn_directive-assembler
481
        je      parse_extrn_directive
482
        cmp     bx,public_directive-assembler
483
        je      parse_public_directive
484
      parse_argument:
485
        lea     eax,[edi+100h]
486
        cmp     eax,[labels_list]
487
        jae     out_of_memory
488
        lods    byte [esi]
489
        cmp     al,':'
490
        je      instruction_separator
491
        cmp     al,','
492
        je      separator
493
        cmp     al,'='
494
        je      separator
495
        cmp     al,'|'
496
        je      separator
497
        cmp     al,'&'
498
        je      separator
499
        cmp     al,'~'
500
        je      separator
501
        cmp     al,'>'
502
        je      greater
503
        cmp     al,'<'
504
        je      less
505
        cmp     al,')'
506
        je      close_parenthesis
507
        or      al,al
508
        jz      contents_parsed
509
        cmp     al,'['
510
        je      address_argument
511
        cmp     al,']'
512
        je      separator
513
        cmp     al,'{'
514
        je      unallowed_character
515
        cmp     al,'}'
516
        je      unallowed_character
517
        cmp     al,'#'
518
        je      unallowed_character
519
        cmp     al,'`'
520
        je      unallowed_character
521
        dec     esi
522
        cmp     al,1Ah
523
        jne     expression_argument
524
        push    edi
525
        mov     edi,directive_operators
526
        call    get_operator
527
        or      al,al
528
        jnz     operator_argument
529
        inc     esi
530
        movzx   ecx,byte [esi]
531
        inc     esi
532
        call    get_symbol
533
        jnc     symbol_argument
534
        cmp     ecx,1
535
        jne     check_argument
536
        cmp     byte [esi],'?'
537
        jne     check_argument
538
        pop     edi
539
        movs    byte [edi],[esi]
540
        jmp     argument_parsed
541
      symbol_argument:
542
        pop     edi
543
        stos    word [edi]
544
        jmp     argument_parsed
545
      operator_argument:
546
        pop     edi
547
        cmp     al,85h
548
        je      ptr_argument
549
        stos    byte [edi]
550
        cmp     al,80h
551
        je      forced_expression
552
        cmp     al,81h
553
        je      forced_parenthesis
554
        cmp     al,82h
555
        je      parse_from_operator
556
        cmp     al,89h
557
        je      parse_label_operator
558
        jmp     argument_parsed
559
      allow_embedded_instruction:
560
        cmp     byte [esi],1Ah
561
        jne     parse_argument
562
        push    edi
563
        inc     esi
564
        movzx   ecx,byte [esi]
565
        inc     esi
566
        call    get_instruction
567
        jnc     embedded_instruction
568
        call    get_data_directive
569
        jnc     embedded_instruction
570
        pop     edi
571
        sub     esi,2
572
        jmp     parse_argument
573
      embedded_instruction:
574
        pop     edi
575
        mov     dl,al
576
        mov     al,1
577
        stos    byte [edi]
578
        mov     ax,bx
579
        stos    word [edi]
580
        mov     al,dl
581
        stos    byte [edi]
582
        jmp     parse_instruction_arguments
583
      parse_times_directive:
584
        mov     al,'('
585
        stos    byte [edi]
586
        call    convert_expression
587
        mov     al,')'
588
        stos    byte [edi]
589
        cmp     byte [esi],':'
590
        jne     allow_embedded_instruction
591
        movs    byte [edi],[esi]
592
        jmp     allow_embedded_instruction
593
      parse_label_directive:
31 halyavin 594
        cmp     byte [esi],1Ah
109 heavyiron 595
        jne     argument_parsed
596
        push    esi
597
        inc     esi
598
        movzx   ecx,byte [esi]
599
        inc     esi
600
        call    identify_label
601
        pop     ebx
602
        cmp     eax,0Fh
603
        je      non_label_identified
604
        mov     byte [edi],2
605
        inc     edi
606
        stos    dword [edi]
607
        xor     al,al
608
        stos    byte [edi]
609
        jmp     argument_parsed
610
      non_label_identified:
611
        mov     esi,ebx
612
        jmp     argument_parsed
613
      parse_load_directive:
31 halyavin 614
        cmp     byte [esi],1Ah
109 heavyiron 615
        jne     argument_parsed
616
        push    esi
617
        inc     esi
618
        movzx   ecx,byte [esi]
619
        inc     esi
620
        call    get_label_id
621
        pop     ebx
622
        cmp     eax,0Fh
623
        je      non_label_identified
624
        mov     byte [edi],2
625
        inc     edi
626
        stos    dword [edi]
627
        xor     al,al
628
        stos    byte [edi]
629
        jmp     argument_parsed
630
      parse_public_directive:
31 halyavin 631
        cmp     byte [esi],1Ah
109 heavyiron 632
        jne     parse_argument
633
        inc     esi
634
        push    esi
635
        movzx   ecx,byte [esi]
636
        inc     esi
637
        mov     al,2
638
        stos    byte [edi]
639
        call    get_label_id
640
        stos    dword [edi]
641
        mov     ax,8600h
642
        stos    word [edi]
643
        pop     ebx
644
        push    ebx esi edi
645
        mov     edi,directive_operators
646
        call    get_operator
647
        pop     edi edx ebx
648
        cmp     al,86h
649
        je      argument_parsed
650
        mov     esi,edx
651
        xchg    esi,ebx
652
        movzx   ecx,byte [esi]
653
        inc     esi
654
        mov     ax,'('
655
        stos    word [edi]
656
        mov     eax,ecx
657
        stos    dword [edi]
658
        rep     movs byte [edi],[esi]
659
        xor     al,al
660
        stos    byte [edi]
661
        xchg    esi,ebx
662
        jmp     argument_parsed
663
      parse_extrn_directive:
31 halyavin 664
        cmp     byte [esi],22h
109 heavyiron 665
        je      parse_quoted_extrn
666
        cmp     byte [esi],1Ah
667
        jne     parse_argument
668
        push    esi
669
        movzx   ecx,byte [esi+1]
670
        add     esi,2
671
        mov     ax,'('
672
        stos    word [edi]
673
        mov     eax,ecx
674
        stos    dword [edi]
675
        rep     movs byte [edi],[esi]
676
        mov     ax,8600h
677
        stos    word [edi]
678
        pop     esi
679
      parse_label_operator:
31 halyavin 680
        cmp     byte [esi],1Ah
109 heavyiron 681
        jne     argument_parsed
682
        inc     esi
683
        movzx   ecx,byte [esi]
684
        inc     esi
685
        mov     al,2
686
        stos    byte [edi]
687
        call    get_label_id
688
        stos    dword [edi]
689
        xor     al,al
690
        stos    byte [edi]
691
        jmp     argument_parsed
692
      parse_from_operator:
31 halyavin 693
        cmp     byte [esi],22h
109 heavyiron 694
        jne     forced_expression
695
        jmp     argument_parsed
696
      parse_quoted_extrn:
31 halyavin 697
        inc     esi
109 heavyiron 698
        mov     ax,'('
699
        stos    word [edi]
700
        lods    dword [esi]
701
        mov     ecx,eax
702
        stos    dword [edi]
703
        rep     movs byte [edi],[esi]
704
        xor     al,al
705
        stos    byte [edi]
706
        push    esi edi
707
        mov     edi,directive_operators
708
        call    get_operator
709
        mov     edx,esi
710
        pop     edi esi
711
        cmp     al,86h
712
        jne     argument_parsed
713
        stos    byte [edi]
714
        mov     esi,edx
715
        jmp     parse_label_operator
716
      ptr_argument:
31 halyavin 717
        call    parse_address
109 heavyiron 718
        jmp     address_parsed
719
      check_argument:
31 halyavin 720
        push    esi ecx
109 heavyiron 721
        sub     esi,2
722
        mov     edi,single_operand_operators
723
        call    get_operator
724
        pop     ecx esi
725
        or      al,al
726
        jnz     not_instruction
727
        call    get_instruction
728
        jnc     embedded_instruction
729
        call    get_data_directive
730
        jnc     embedded_instruction
731
      not_instruction:
31 halyavin 732
        pop     edi
109 heavyiron 733
        sub     esi,2
734
      expression_argument:
31 halyavin 735
        cmp     byte [esi],22h
109 heavyiron 736
        jne     not_string
737
        mov     eax,[esi+1]
738
        lea     ebx,[esi+5+eax]
739
        push    ebx ecx esi edi
740
        mov     al,'('
741
        stos    byte [edi]
742
        call    convert_expression
743
        mov     al,')'
744
        stos    byte [edi]
745
        pop     eax edx ecx ebx
746
        cmp     esi,ebx
747
        jne     expression_parsed
748
        mov     edi,eax
749
        mov     esi,edx
750
      string_argument:
31 halyavin 751
        inc     esi
109 heavyiron 752
        mov     ax,'('
753
        stos    word [edi]
754
        lods    dword [esi]
755
        mov     ecx,eax
756
        stos    dword [edi]
757
        shr     ecx,1
758
        jnc     string_movsb_ok
759
        movs    byte [edi],[esi]
760
      string_movsb_ok:
31 halyavin 761
        shr     ecx,1
109 heavyiron 762
        jnc     string_movsw_ok
763
        movs    word [edi],[esi]
764
      string_movsw_ok:
31 halyavin 765
        rep     movs dword [edi],[esi]
109 heavyiron 766
        xor     al,al
767
        stos    byte [edi]
768
        jmp     expression_parsed
769
      not_string:
31 halyavin 770
        cmp     byte [esi],'('
109 heavyiron 771
        jne     expression
772
        mov     eax,esp
773
        sub     eax,100h
774
        jc      stack_overflow
775
        cmp     eax,[stack_limit]
776
        jb      stack_overflow
777
        push    esi edi
778
        inc     esi
779
        mov     al,'{'
780
        stos    byte [edi]
781
        inc     [parenthesis_stack]
782
        jmp     parse_argument
783
      expression:
31 halyavin 784
        mov     al,'('
109 heavyiron 785
        stos    byte [edi]
786
        call    convert_expression
787
        mov     al,')'
788
        stos    byte [edi]
789
        jmp     expression_parsed
790
      forced_expression:
31 halyavin 791
        mov     al,'('
109 heavyiron 792
        stos    byte [edi]
793
        call    convert_expression
794
        mov     al,')'
795
        stos    byte [edi]
796
        jmp     argument_parsed
797
      address_argument:
31 halyavin 798
        call    parse_address
109 heavyiron 799
        lods    byte [esi]
800
        cmp     al,']'
801
        je      address_parsed
802
        dec     esi
803
        mov     al,')'
804
        stos    byte [edi]
805
        jmp     argument_parsed
806
      address_parsed:
31 halyavin 807
        mov     al,']'
109 heavyiron 808
        stos    byte [edi]
809
        jmp     argument_parsed
810
      parse_address:
31 halyavin 811
        mov     al,'['
109 heavyiron 812
        stos    byte [edi]
813
        cmp     word [esi],021Ah
814
        jne     convert_address
815
        push    esi
816
        add     esi,4
817
        lea     ebx,[esi+1]
818
        cmp     byte [esi],':'
819
        pop     esi
820
        jne     convert_address
821
        add     esi,2
822
        mov     ecx,2
823
        push    ebx edi
824
        call    get_symbol
825
        pop     edi esi
826
        jc      unknown_segment_prefix
827
        cmp     al,10h
828
        jne     unknown_segment_prefix
829
        mov     al,ah
830
        and     ah,11110000b
831
        cmp     ah,60h
832
        jne     unknown_segment_prefix
833
        stos    byte [edi]
834
        jmp     convert_address
835
      unknown_segment_prefix:
836
        sub     esi,5
837
      convert_address:
31 halyavin 838
        push    edi
109 heavyiron 839
        mov     edi,address_sizes
840
        call    get_operator
841
        pop     edi
842
        or      al,al
843
        jz      convert_expression
844
        add     al,70h
845
        stos    byte [edi]
846
        jmp     convert_expression
847
      forced_parenthesis:
31 halyavin 848
        cmp     byte [esi],'('
109 heavyiron 849
        jne     argument_parsed
850
        inc     esi
851
        mov     al,'{'
852
        jmp     separator
853
      unallowed_character:
31 halyavin 854
        mov     al,0FFh
109 heavyiron 855
        jmp     separator
856
      close_parenthesis:
31 halyavin 857
        mov     al,'}'
109 heavyiron 858
      separator:
31 halyavin 859
        stos    byte [edi]
109 heavyiron 860
        jmp     argument_parsed
861
      instruction_separator:
31 halyavin 862
        stos    byte [edi]
109 heavyiron 863
        jmp     allow_embedded_instruction
864
      greater:
31 halyavin 865
        cmp     byte [esi],'='
109 heavyiron 866
        jne     separator
867
        inc     esi
868
        mov     al,0F2h
869
        jmp     separator
870
      less:
31 halyavin 871
        cmp     byte [edi-1],0F6h
109 heavyiron 872
        je      separator
873
        cmp     byte [esi],'>'
874
        je      not_equal
875
        cmp     byte [esi],'='
876
        jne     separator
877
        inc     esi
878
        mov     al,0F3h
879
        jmp     separator
880
      not_equal:
31 halyavin 881
        inc     esi
109 heavyiron 882
        mov     al,0F1h
883
        jmp     separator
884
      argument_parsed:
31 halyavin 885
        cmp     [parenthesis_stack],0
109 heavyiron 886
        je      parse_argument
887
        dec     [parenthesis_stack]
888
        add     esp,8
889
        jmp     argument_parsed
890
      expression_parsed:
31 halyavin 891
        cmp     [parenthesis_stack],0
109 heavyiron 892
        je      parse_argument
893
        cmp     byte [esi],')'
894
        jne     argument_parsed
895
        dec     [parenthesis_stack]
896
        pop     edi esi
897
        jmp     expression
898
      contents_parsed:
899
        cmp     [parenthesis_stack],0
900
        jne     invalid_expression
901
        ret
902
31 halyavin 903
 
109 heavyiron 904
        cmp     byte [esi],'.'
905
        je      local_label_name
906
        call    get_label_id
907
        cmp     eax,10h
908
        jb      label_identified
909
        or      ebx,ebx
910
        jz      anonymous_label_name
911
        dec     ebx
912
        mov     [current_locals_prefix],ebx
913
      label_identified:
914
        ret
915
      anonymous_label_name:
916
        cmp     byte [esi-1],'@'
917
        je      anonymous_label_name_ok
918
        mov     eax,0Fh
919
      anonymous_label_name_ok:
920
        ret
921
      local_label_name:
922
        call    get_label_id
923
        ret
924
925
 
31 halyavin 926
        cmp     byte [esi],1Ah
109 heavyiron 927
        jne     get_simple_operator
928
        mov     edx,esi
929
        push    ebp
930
        inc     esi
931
        lods    byte [esi]
932
        movzx   ebp,al
933
        push    edi
934
        mov     ecx,ebp
935
        call    lower_case
936
        pop     edi
937
      check_operator:
31 halyavin 938
        mov     esi,converted
109 heavyiron 939
        movzx   ecx,byte [edi]
940
        jecxz   no_operator
941
        inc     edi
942
        mov     ebx,edi
943
        add     ebx,ecx
944
        cmp     ecx,ebp
945
        jne     next_operator
946
        repe    cmps byte [esi],[edi]
947
        je      operator_found
948
      next_operator:
31 halyavin 949
        mov     edi,ebx
109 heavyiron 950
        inc     edi
951
        jmp     check_operator
952
      no_operator:
31 halyavin 953
        mov     esi,edx
109 heavyiron 954
        mov     ecx,ebp
955
        pop     ebp
956
      no_simple_operator:
31 halyavin 957
        xor     al,al
109 heavyiron 958
        ret
959
      operator_found:
31 halyavin 960
        lea     esi,[edx+2+ebp]
109 heavyiron 961
        mov     ecx,ebp
962
        pop     ebp
963
        mov     al,[edi]
964
        ret
965
      get_simple_operator:
31 halyavin 966
        mov     al,[esi]
109 heavyiron 967
        cmp     al,22h
968
        je      no_simple_operator
969
      simple_operator:
31 halyavin 970
        cmp     byte [edi],1
109 heavyiron 971
        jb      no_simple_operator
972
        ja      simple_next_operator
973
        cmp     al,[edi+1]
974
        je      simple_operator_found
975
      simple_next_operator:
31 halyavin 976
        movzx   ecx,byte [edi]
109 heavyiron 977
        lea     edi,[edi+1+ecx+1]
978
        jmp     simple_operator
979
      simple_operator_found:
31 halyavin 980
        inc     esi
109 heavyiron 981
        mov     al,[edi+2]
982
        ret
983
31 halyavin 984
 
985
        push    esi
109 heavyiron 986
        mov     ebp,ecx
987
        call    lower_case
988
        mov     ecx,ebp
989
        cmp     cl,11
990
        ja      no_symbol
991
        sub     cl,2
992
        jc      no_symbol
993
        movzx   ebx,word [symbols+ecx*4]
994
        add     ebx,symbols
995
        movzx   edx,word [symbols+ecx*4+2]
996
      scan_symbols:
31 halyavin 997
        or      edx,edx
109 heavyiron 998
        jz      no_symbol
999
        mov     eax,edx
1000
        shr     eax,1
1001
        lea     edi,[ebp+2]
1002
        imul    eax,edi
1003
        lea     edi,[ebx+eax]
1004
        mov     esi,converted
1005
        mov     ecx,ebp
1006
        repe    cmps byte [esi],[edi]
1007
        ja      symbols_up
1008
        jb      symbols_down
1009
        pop     esi
1010
        add     esi,ebp
1011
        mov     ax,[edi]
1012
        clc
1013
        ret
1014
      no_symbol:
31 halyavin 1015
        pop     esi
109 heavyiron 1016
        mov     ecx,ebp
1017
        stc
1018
        ret
1019
      symbols_down:
1020
        shr     edx,1
1021
        jmp     scan_symbols
1022
      symbols_up:
1023
        lea     ebx,[edi+ecx+2]
1024
        shr     edx,1
1025
        adc     edx,-1
1026
        jmp     scan_symbols
1027
31 halyavin 1028
 
109 heavyiron 1029
        push    esi
1030
        mov     ebp,ecx
1031
        call    lower_case
1032
        mov     ecx,ebp
1033
        cmp     cl,4
1034
        ja      no_instruction
1035
        sub     cl,2
1036
        jc      no_instruction
1037
        movzx   ebx,word [data_directives+ecx*4]
1038
        add     ebx,data_directives
1039
        movzx   edx,word [data_directives+ecx*4+2]
1040
        jmp     scan_instructions
1041
1042
 
31 halyavin 1043
        push    esi
109 heavyiron 1044
        mov     ebp,ecx
1045
        call    lower_case
1046
        mov     ecx,ebp
1047
        cmp     cl,11
1048
        ja      no_instruction
1049
        sub     cl,2
1050
        jc      no_instruction
1051
        movzx   ebx,word [instructions+ecx*4]
1052
        add     ebx,instructions
1053
        movzx   edx,word [instructions+ecx*4+2]
1054
      scan_instructions:
31 halyavin 1055
        or      edx,edx
109 heavyiron 1056
        jz      no_instruction
1057
        mov     eax,edx
1058
        shr     eax,1
1059
        lea     edi,[ebp+3]
1060
        imul    eax,edi
1061
        lea     edi,[ebx+eax]
1062
        mov     esi,converted
1063
        mov     ecx,ebp
1064
        repe    cmps byte [esi],[edi]
1065
        ja      instructions_up
1066
        jb      instructions_down
1067
        pop     esi
1068
        add     esi,ebp
1069
        mov     al,[edi]
1070
        mov     bx,[edi+1]
1071
        clc
1072
        ret
1073
      no_instruction:
31 halyavin 1074
        pop     esi
109 heavyiron 1075
        mov     ecx,ebp
1076
        stc
1077
        ret
1078
      instructions_down:
1079
        shr     edx,1
1080
        jmp     scan_instructions
1081
      instructions_up:
1082
        lea     ebx,[edi+ecx+3]
1083
        shr     edx,1
1084
        adc     edx,-1
1085
        jmp     scan_instructions
1086
31 halyavin 1087
 
1088
        cmp     ecx,100h
109 heavyiron 1089
        jae     name_too_long
1090
        cmp     byte [esi],'@'
1091
        je      anonymous_label
1092
        cmp     byte [esi],'.'
1093
        jne     standard_label
1094
        cmp     byte [esi+1],'.'
1095
        je      standard_label
1096
        cmp     [current_locals_prefix],0
1097
        je      standard_label
1098
        push    edi
1099
        mov     edi,[additional_memory_end]
1100
        sub     edi,2
1101
        sub     edi,ecx
1102
        push    ecx esi
1103
        mov     esi,[current_locals_prefix]
1104
        lods    byte [esi]
1105
        movzx   ecx,al
1106
        sub     edi,ecx
1107
        cmp     edi,[free_additional_memory]
1108
        jb      out_of_memory
1109
        mov     word [edi],0
1110
        add     edi,2
1111
        mov     ebx,edi
1112
        rep     movs byte [edi],[esi]
1113
        pop     esi ecx
1114
        add     al,cl
1115
        jc      name_too_long
1116
        rep     movs byte [edi],[esi]
1117
        pop     edi
1118
        push    ebx esi
1119
        movzx   ecx,al
1120
        mov     byte [ebx-1],al
1121
        mov     esi,ebx
1122
        call    get_label_id
1123
        pop     esi ebx
1124
        cmp     ebx,[eax+24]
1125
        jne     composed_label_id_ok
1126
        lea     edx,[ebx-2]
1127
        mov     [additional_memory_end],edx
1128
      composed_label_id_ok:
1129
        ret
1130
      anonymous_label:
31 halyavin 1131
        cmp     ecx,2
109 heavyiron 1132
        jne     standard_label
1133
        mov     al,[esi+1]
1134
        mov     ebx,characters
1135
        xlat    byte [ebx]
1136
        cmp     al,'@'
1137
        je      new_anonymous
1138
        cmp     al,'b'
1139
        je      anonymous_back
1140
        cmp     al,'r'
1141
        je      anonymous_back
1142
        cmp     al,'f'
1143
        jne     standard_label
1144
        add     esi,2
1145
        mov     eax,[anonymous_forward]
1146
        or      eax,eax
1147
        jnz     anonymous_ok
1148
        mov     eax,[current_line]
1149
        mov     [error_line],eax
1150
        call    allocate_label
1151
        mov     [anonymous_forward],eax
1152
      anonymous_ok:
31 halyavin 1153
        xor     ebx,ebx
109 heavyiron 1154
        ret
1155
      anonymous_back:
31 halyavin 1156
        add     esi,2
109 heavyiron 1157
        mov     eax,[anonymous_reverse]
1158
        or      eax,eax
1159
        jz      invalid_value
1160
        jmp     anonymous_ok
1161
      new_anonymous:
31 halyavin 1162
        add     esi,2
109 heavyiron 1163
        mov     eax,[anonymous_forward]
1164
        or      eax,eax
1165
        jnz     new_anonymous_ok
1166
        call    allocate_label
1167
      new_anonymous_ok:
31 halyavin 1168
        mov     [anonymous_reverse],eax
109 heavyiron 1169
        mov     [anonymous_forward],0
1170
        jmp     anonymous_ok
1171
      standard_label:
31 halyavin 1172
        cmp     byte [esi],'%'
109 heavyiron 1173
        je      get_predefined_id
1174
        cmp     byte [esi],'$'
1175
        jne     find_label
1176
        cmp     ecx,2
1177
        ja      find_label
1178
        inc     esi
1179
        jb      get_current_offset_id
1180
        inc     esi
1181
        cmp     byte [esi-1],'$'
1182
        je      get_org_origin_id
1183
        sub     esi,ecx
1184
        jmp     find_label
1185
      get_current_offset_id:
31 halyavin 1186
        xor     eax,eax
109 heavyiron 1187
        ret
1188
      get_counter_id:
31 halyavin 1189
        mov     eax,1
109 heavyiron 1190
        ret
1191
      get_timestamp_id:
31 halyavin 1192
        mov     eax,2
109 heavyiron 1193
        ret
1194
      get_org_origin_id:
31 halyavin 1195
        mov     eax,3
109 heavyiron 1196
        ret
1197
      get_predefined_id:
31 halyavin 1198
        cmp     ecx,2
109 heavyiron 1199
        ja      find_label
1200
        inc     esi
1201
        cmp     cl,1
1202
        je      get_counter_id
1203
        lods    byte [esi]
1204
        mov     ebx,characters
1205
        xlat    [ebx]
1206
        cmp     al,'t'
1207
        je      get_timestamp_id
1208
        sub     esi,2
1209
      find_label:
31 halyavin 1210
        xor     ebx,ebx
109 heavyiron 1211
        mov     eax,2166136261
1212
        mov     ebp,16777619
1213
      hash_label:
31 halyavin 1214
        xor     al,[esi+ebx]
109 heavyiron 1215
        mul     ebp
1216
        inc     bl
1217
        cmp     bl,cl
1218
        jb      hash_label
1219
        mov     ebp,eax
1220
        shl     eax,8
1221
        and     ebp,0FFh shl 24
1222
        xor     ebp,eax
1223
        or      ebp,ebx
1224
        mov     [label_hash],ebp
1225
        push    edi esi
1226
        push    ecx
1227
        mov     ecx,32
1228
        mov     ebx,hash_tree
1229
      follow_tree:
31 halyavin 1230
        mov     edx,[ebx]
109 heavyiron 1231
        or      edx,edx
1232
        jz      extend_tree
1233
        xor     eax,eax
1234
        shl     ebp,1
1235
        adc     eax,0
1236
        lea     ebx,[edx+eax*4]
1237
        dec     ecx
1238
        jnz     follow_tree
1239
        mov     [label_leaf],ebx
1240
        pop     edx
1241
        mov     eax,[ebx]
1242
        or      eax,eax
1243
        jz      add_label
1244
        mov     ebx,esi
1245
        mov     ebp,[label_hash]
1246
      compare_labels:
31 halyavin 1247
        mov     esi,ebx
109 heavyiron 1248
        mov     ecx,edx
1249
        mov     edi,[eax+4]
1250
        mov     edi,[edi+24]
1251
        repe    cmps byte [esi],[edi]
1252
        je      label_found
1253
        mov     eax,[eax]
1254
        or      eax,eax
1255
        jnz     compare_labels
1256
        jmp     add_label
1257
      label_found:
31 halyavin 1258
        add     esp,4
109 heavyiron 1259
        pop     edi
1260
        mov     eax,[eax+4]
1261
        ret
1262
      extend_tree:
31 halyavin 1263
        mov     edx,[free_additional_memory]
109 heavyiron 1264
        lea     eax,[edx+8]
1265
        cmp     eax,[additional_memory_end]
1266
        ja      out_of_memory
1267
        mov     [free_additional_memory],eax
1268
        xor     eax,eax
1269
        mov     [edx],eax
1270
        mov     [edx+4],eax
1271
        shl     ebp,1
1272
        adc     eax,0
1273
        mov     [ebx],edx
1274
        lea     ebx,[edx+eax*4]
1275
        dec     ecx
1276
        jnz     extend_tree
1277
        mov     [label_leaf],ebx
1278
        pop     edx
1279
      add_label:
31 halyavin 1280
        mov     ecx,edx
109 heavyiron 1281
        pop     esi
1282
        cmp     byte [esi-2],0
1283
        je      label_name_ok
1284
        mov     al,[esi]
1285
        cmp     al,30h
1286
        jb      name_first_char_ok
1287
        cmp     al,39h
1288
        jbe     invalid_name
1289
      name_first_char_ok:
31 halyavin 1290
        cmp     ecx,1
109 heavyiron 1291
        jne     check_for_reserved_word
1292
        cmp     al,'$'
1293
        je      reserved_word
1294
      check_for_reserved_word:
31 halyavin 1295
        call    get_instruction
109 heavyiron 1296
        jnc     reserved_word
1297
        call    get_data_directive
1298
        jnc     reserved_word
1299
        call    get_symbol
1300
        jnc     reserved_word
1301
        sub     esi,2
1302
        mov     edi,operators
1303
        call    get_operator
1304
        or      al,al
1305
        jnz     reserved_word
1306
        mov     edi,single_operand_operators
1307
        call    get_operator
1308
        or      al,al
1309
        jnz     reserved_word
1310
        mov     edi,directive_operators
1311
        call    get_operator
1312
        or      al,al
1313
        jnz     reserved_word
1314
        inc     esi
1315
        movzx   ecx,byte [esi]
1316
        inc     esi
1317
      label_name_ok:
31 halyavin 1318
        mov     edx,[free_additional_memory]
109 heavyiron 1319
        lea     eax,[edx+8]
1320
        cmp     eax,[additional_memory_end]
1321
        ja      out_of_memory
1322
        mov     [free_additional_memory],eax
1323
        mov     ebx,esi
1324
        add     esi,ecx
1325
        mov     eax,[label_leaf]
1326
        mov     edi,[eax]
1327
        mov     [edx],edi
1328
        mov     [eax],edx
1329
        call    allocate_label
1330
        mov     [edx+4],eax
1331
        mov     [eax+24],ebx
1332
        pop     edi
1333
        ret
1334
      reserved_word:
31 halyavin 1335
        mov     eax,0Fh
109 heavyiron 1336
        pop     edi
1337
        ret
1338
      allocate_label:
1339
        mov     eax,[labels_list]
1340
        mov     ecx,LABEL_STRUCTURE_SIZE shr 2
1341
      initialize_label:
1342
        sub     eax,4
1343
        mov     dword [eax],0
1344
        loop    initialize_label
1345
        mov     [labels_list],eax
1346
        ret
1347
31 halyavin 1348
 
109 heavyiron 1349
>