Subversion Repositories Kolibri OS

Rev

Rev 692 | 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-2007, Tomasz Grysztar.
340 heavyiron 3
; All rights reserved.
31 halyavin 4
5
 
6
	mov	edi,characters
157 heavyiron 7
	xor	al,al
8
      make_characters_table:
31 halyavin 9
	stosb
157 heavyiron 10
	inc	al
11
	jnz	make_characters_table
253 heavyiron 12
	mov	esi,characters+'a'
157 heavyiron 13
	mov	edi,characters+'A'
14
	mov	ecx,26
15
	rep	movsb
16
	mov	edi,characters
17
	mov	esi,symbol_characters+1
18
	movzx	ecx,byte [esi-1]
19
	xor	eax,eax
20
      mark_symbol_characters:
31 halyavin 21
	lodsb
157 heavyiron 22
	mov	byte [edi+eax],0
23
	loop	mark_symbol_characters
24
	mov	edi,locals_counter
25
	mov	ax,1 + '0' shl 8
692 heavyiron 26
	stos	word [edi]
27
	mov	edi,[memory_start]
157 heavyiron 28
	mov	[include_paths],edi
29
	mov	esi,include_variable
30
	call	get_environment_variable
31
	xor	al,al
32
	stosb
33
	mov	[memory_start],edi
34
	mov	eax,[additional_memory]
35
	mov	[free_additional_memory],eax
36
	mov	eax,[additional_memory_end]
37
	mov	[labels_list],eax
38
	xor	eax,eax
39
	mov	[display_buffer],eax
40
	mov	[hash_tree],eax
41
	mov	[macro_status],al
42
692 heavyiron 43
 
44
      process_predefinitions:
45
	movzx	ecx,byte [esi]
46
	test	ecx,ecx
47
	jz	predefinitions_ok
48
	inc	esi
49
	lea	eax,[esi+ecx]
50
	push	eax
51
	mov	ch,10b
52
	call	add_preprocessor_symbol
53
	pop	esi
54
	mov	edi,[memory_start]
55
	mov	[edx+8],edi
56
      convert_predefinition:
57
	cmp	edi,[memory_end]
58
	jae	out_of_memory
59
	lods	byte [esi]
60
	or	al,al
61
	jz	predefinition_converted
62
	cmp	al,20h
63
	je	convert_predefinition
64
	mov	ah,al
65
	mov	ebx,characters
66
	xlat	byte [ebx]
67
	or	al,al
68
	jz	predefinition_separator
69
	cmp	ah,27h
70
	je	predefinition_string
71
	cmp	ah,22h
72
	je	predefinition_string
73
	mov	byte [edi],1Ah
74
	scas	word [edi]
75
	xchg	al,ah
76
	stos	byte [edi]
77
	mov	ebx,characters
78
	xor	ecx,ecx
79
      predefinition_symbol:
80
	lods	byte [esi]
81
	stos	byte [edi]
82
	xlat	byte [ebx]
83
	or	al,al
84
	loopnzd predefinition_symbol
85
	neg	ecx
86
	cmp	ecx,255
87
	ja	invalid_definition
88
	mov	ebx,edi
89
	sub	ebx,ecx
90
	mov	byte [ebx-2],cl
91
      found_predefinition_separator:
92
	dec	edi
93
	mov	ah,[esi-1]
94
      predefinition_separator:
95
	xchg	al,ah
96
	or	al,al
97
	jz	predefinition_converted
98
	cmp	al,20h
99
	je	convert_line_data
100
	cmp	al,3Bh
101
	je	invalid_definition
102
	cmp	al,5Ch
103
	je	predefinition_backslash
104
	stos	byte [edi]
105
	jmp	convert_predefinition
106
      predefinition_string:
107
	mov	al,22h
108
	stos	byte [edi]
109
	scas	dword [edi]
110
	mov	ebx,edi
111
      copy_predefinition_string:
112
	lods	byte [esi]
113
	stos	byte [edi]
114
	or	al,al
115
	jz	invalid_definition
116
	cmp	al,ah
117
	jne	copy_predefinition_string
118
	lods	byte [esi]
119
	cmp	al,ah
120
	je	copy_predefinition_string
121
	dec	esi
122
	dec	edi
123
	mov	eax,edi
124
	sub	eax,ebx
125
	mov	[ebx-4],eax
126
	jmp	convert_predefinition
127
      predefinition_backslash:
128
	mov	byte [edi],0
129
	lods	byte [esi]
130
	or	al,al
131
	jz	invalid_definition
132
	cmp	al,20h
133
	je	invalid_definition
134
	cmp	al,3Bh
135
	je	invalid_definition
136
	mov	al,1Ah
137
	stos	byte [edi]
138
	mov	ecx,edi
139
	mov	ax,5C01h
140
	stos	word [edi]
141
	dec	esi
142
      group_predefinition_backslashes:
143
	lods	byte [esi]
144
	cmp	al,5Ch
145
	jne	predefinition_backslashed_symbol
146
	stos	byte [edi]
147
	inc	byte [ecx]
148
	jmp	group_predefinition_backslashes
149
      predefinition_backslashed_symbol:
150
	cmp	al,20h
151
	je	invalid_definition
152
	cmp	al,22h
153
	je	invalid_definition
154
	cmp	al,27h
155
	je	invalid_definition
156
	cmp	al,3Bh
157
	je	invalid_definition
158
	mov	ah,al
159
	mov	ebx,characters
160
	xlat	byte [ebx]
161
	or	al,al
162
	jz	predefinition_backslashed_symbol_character
163
	mov	al,ah
164
      convert_predefinition_backslashed_symbol:
165
	stos	byte [edi]
166
	xlat	byte [ebx]
167
	or	al,al
168
	jz	found_predefinition_separator
169
	inc	byte [ecx]
170
	jz	invalid_definition
171
	lods	byte [esi]
172
	jmp	convert_predefinition_backslashed_symbol
173
      predefinition_backslashed_symbol_character:
174
	mov	al,ah
175
	stos	byte [edi]
176
	inc	byte [ecx]
177
	jmp	convert_predefinition
178
      predefinition_converted:
179
	mov	[memory_start],edi
180
	sub	edi,[edx+8]
181
	mov	[edx+12],edi
182
	jmp	process_predefinitions
183
      predefinitions_ok:
184
185
 
157 heavyiron 186
	mov	edx,esi
187
	call	open
188
	jc	main_file_not_found
189
	mov	edi,[memory_start]
190
	call	preprocess_file
191
	mov	eax,[error_line]
192
	mov	[current_line],eax
193
	cmp	[macro_status],0
194
	jne	incomplete_macro
195
	mov	[source_start],edi
196
	ret
197
31 halyavin 198
 
199
	push	[memory_end]
157 heavyiron 200
	push	esi
201
	mov	al,2
202
	xor	edx,edx
203
	call	lseek
204
	push	eax
205
	xor	al,al
206
	xor	edx,edx
207
	call	lseek
208
	pop	ecx
209
	mov	edx,[memory_end]
210
	dec	edx
211
	mov	byte [edx],1Ah
212
	sub	edx,ecx
213
	jc	out_of_memory
214
	mov	esi,edx
215
	cmp	edx,edi
216
	jbe	out_of_memory
217
	mov	[memory_end],edx
218
	call	read
219
	call	close
220
	pop	edx
221
	xor	ecx,ecx
222
	mov	ebx,esi
223
      preprocess_source:
31 halyavin 224
	inc	ecx
157 heavyiron 225
	mov	[current_line],edi
226
	mov	eax,edx
227
	stos	dword [edi]
228
	mov	eax,ecx
229
	stos	dword [edi]
230
	mov	eax,esi
231
	sub	eax,ebx
232
	stos	dword [edi]
233
	xor	eax,eax
234
	stos	dword [edi]
235
	push	ebx edx
236
	call	convert_line
237
	call	preprocess_line
238
	pop	edx ebx
239
      next_line:
31 halyavin 240
	cmp	byte [esi-1],1Ah
157 heavyiron 241
	jne	preprocess_source
242
      file_end:
31 halyavin 243
	pop	[memory_end]
157 heavyiron 244
	clc
245
	ret
246
31 halyavin 247
 
248
	push	ecx
157 heavyiron 249
	test	[macro_status],0Fh
250
	jz	convert_line_data
251
	mov	ax,3Bh
252
	stos	word [edi]
253
      convert_line_data:
31 halyavin 254
	cmp	edi,[memory_end]
157 heavyiron 255
	jae	out_of_memory
256
	lods	byte [esi]
257
	cmp	al,20h
258
	je	convert_line_data
259
	cmp	al,9
260
	je	convert_line_data
261
	mov	ah,al
262
	mov	ebx,characters
263
	xlat	byte [ebx]
264
	or	al,al
265
	jz	convert_separator
266
	cmp	ah,27h
267
	je	convert_string
268
	cmp	ah,22h
269
	je	convert_string
270
	mov	byte [edi],1Ah
271
	scas	word [edi]
272
	xchg	al,ah
273
	stos	byte [edi]
274
	mov	ebx,characters
275
	xor	ecx,ecx
276
      convert_symbol:
31 halyavin 277
	lods	byte [esi]
157 heavyiron 278
	stos	byte [edi]
279
	xlat	byte [ebx]
280
	or	al,al
281
	loopnzd convert_symbol
282
	neg	ecx
283
	cmp	ecx,255
284
	ja	name_too_long
285
	mov	ebx,edi
286
	sub	ebx,ecx
287
	mov	byte [ebx-2],cl
288
      found_separator:
31 halyavin 289
	dec	edi
157 heavyiron 290
	mov	ah,[esi-1]
291
      convert_separator:
31 halyavin 292
	xchg	al,ah
157 heavyiron 293
	cmp	al,20h
294
	jb	control_character
295
	je	convert_line_data
296
      symbol_character:
31 halyavin 297
	cmp	al,3Bh
157 heavyiron 298
	je	ignore_comment
299
	cmp	al,5Ch
300
	je	backslash_character
301
	stos	byte [edi]
302
	jmp	convert_line_data
303
      control_character:
31 halyavin 304
	cmp	al,1Ah
157 heavyiron 305
	je	line_end
306
	cmp	al,0Dh
307
	je	cr_character
308
	cmp	al,0Ah
309
	je	lf_character
310
	cmp	al,9
311
	je	convert_line_data
312
	or	al,al
313
	jnz	symbol_character
314
	jmp	line_end
315
      lf_character:
31 halyavin 316
	lods	byte [esi]
157 heavyiron 317
	cmp	al,0Dh
318
	je	line_end
319
	dec	esi
320
	jmp	line_end
321
      cr_character:
31 halyavin 322
	lods	byte [esi]
157 heavyiron 323
	cmp	al,0Ah
324
	je	line_end
325
	dec	esi
326
	jmp	line_end
327
      convert_string:
31 halyavin 328
	mov	al,22h
157 heavyiron 329
	stos	byte [edi]
330
	scas	dword [edi]
331
	mov	ebx,edi
332
      copy_string:
31 halyavin 333
	lods	byte [esi]
157 heavyiron 334
	stos	byte [edi]
335
	cmp	al,0Ah
336
	je	missing_end_quote
337
	cmp	al,0Dh
338
	je	missing_end_quote
339
	or	al,al
340
	jz	missing_end_quote
341
	cmp	al,1Ah
342
	je	missing_end_quote
343
	cmp	al,ah
344
	jne	copy_string
345
	lods	byte [esi]
346
	cmp	al,ah
347
	je	copy_string
348
	dec	esi
349
	dec	edi
350
	mov	eax,edi
351
	sub	eax,ebx
352
	mov	[ebx-4],eax
353
	jmp	convert_line_data
354
      backslash_character:
31 halyavin 355
	mov	byte [edi],0
157 heavyiron 356
	lods	byte [esi]
357
	cmp	al,20h
358
	je	concatenate_lines
359
	cmp	al,9
360
	je	concatenate_lines
361
	cmp	al,1Ah
362
	je	unexpected_end_of_file
363
	cmp	al,0Ah
364
	je	concatenate_lf
365
	cmp	al,0Dh
366
	je	concatenate_cr
367
	cmp	al,3Bh
368
	je	find_concatenated_line
369
	mov	al,1Ah
370
	stos	byte [edi]
371
	mov	ecx,edi
372
	mov	ax,5C01h
373
	stos	word [edi]
374
	dec	esi
375
      group_backslashes:
31 halyavin 376
	lods	byte [esi]
157 heavyiron 377
	cmp	al,5Ch
378
	jne	backslashed_symbol
379
	stos	byte [edi]
380
	inc	byte [ecx]
381
	jmp	group_backslashes
382
      backslashed_symbol:
31 halyavin 383
	cmp	al,1Ah
157 heavyiron 384
	je	unexpected_end_of_file
385
	cmp	al,0Ah
386
	je	extra_characters_on_line
387
	cmp	al,0Dh
388
	je	extra_characters_on_line
389
	cmp	al,20h
390
	je	extra_characters_on_line
391
	cmp	al,9
392
	je	extra_characters_on_line
393
	cmp	al,22h
394
	je	extra_characters_on_line
395
	cmp	al,27h
396
	je	extra_characters_on_line
397
	cmp	al,3Bh
398
	je	extra_characters_on_line
399
	mov	ah,al
400
	mov	ebx,characters
401
	xlat	byte [ebx]
402
	or	al,al
403
	jz	backslashed_symbol_character
404
	mov	al,ah
405
      convert_backslashed_symbol:
31 halyavin 406
	stos	byte [edi]
157 heavyiron 407
	xlat	byte [ebx]
408
	or	al,al
409
	jz	found_separator
410
	inc	byte [ecx]
411
	jz	name_too_long
412
	lods	byte [esi]
413
	jmp	convert_backslashed_symbol
414
      backslashed_symbol_character:
31 halyavin 415
	mov	al,ah
157 heavyiron 416
	stos	byte [edi]
417
	inc	byte [ecx]
418
	jmp	convert_line_data
419
      concatenate_lines:
31 halyavin 420
	lods	byte [esi]
157 heavyiron 421
	cmp	al,20h
422
	je	concatenate_lines
423
	cmp	al,9
424
	je	concatenate_lines
425
	cmp	al,1Ah
426
	je	unexpected_end_of_file
427
	cmp	al,0Ah
428
	je	concatenate_lf
429
	cmp	al,0Dh
430
	je	concatenate_cr
431
	cmp	al,3Bh
432
	jne	extra_characters_on_line
433
      find_concatenated_line:
31 halyavin 434
	lods	byte [esi]
157 heavyiron 435
	cmp	al,0Ah
436
	je	concatenate_lf
437
	cmp	al,0Dh
438
	je	concatenate_cr
439
	or	al,al
440
	jz	concatenate_ok
441
	cmp	al,1Ah
442
	jne	find_concatenated_line
443
	jmp	unexpected_end_of_file
444
      concatenate_lf:
31 halyavin 445
	lods	byte [esi]
157 heavyiron 446
	cmp	al,0Dh
447
	je	concatenate_ok
448
	dec	esi
449
	jmp	concatenate_ok
450
      concatenate_cr:
31 halyavin 451
	lods	byte [esi]
157 heavyiron 452
	cmp	al,0Ah
453
	je	concatenate_ok
454
	dec	esi
455
      concatenate_ok:
31 halyavin 456
	inc	dword [esp]
157 heavyiron 457
	jmp	convert_line_data
458
      ignore_comment:
31 halyavin 459
	lods	byte [esi]
157 heavyiron 460
	cmp	al,0Ah
461
	je	lf_character
462
	cmp	al,0Dh
463
	je	cr_character
464
	or	al,al
465
	jz	line_end
466
	cmp	al,1Ah
467
	jne	ignore_comment
468
      line_end:
31 halyavin 469
	xor	al,al
157 heavyiron 470
	stos	byte [edi]
471
	pop	ecx
472
	ret
473
31 halyavin 474
 
109 heavyiron 475
	mov	edi,converted
157 heavyiron 476
	mov	ebx,characters
477
      convert_case:
109 heavyiron 478
	lods	byte [esi]
157 heavyiron 479
	xlat	byte [ebx]
480
	stos	byte [edi]
481
	loop	convert_case
482
      case_ok:
109 heavyiron 483
	ret
157 heavyiron 484
109 heavyiron 485
 
486
	push	edi
157 heavyiron 487
	mov	edx,esi
488
	mov	ebp,ecx
489
	call	lower_case
490
	pop	edi
491
      scan_directives:
109 heavyiron 492
	mov	esi,converted
157 heavyiron 493
	movzx	eax,byte [edi]
494
	or	al,al
495
	jz	no_directive
496
	mov	ecx,ebp
497
	inc	edi
498
	mov	ebx,edi
499
	add	ebx,eax
500
	mov	ah,[esi]
501
	cmp	ah,[edi]
502
	jb	no_directive
503
	ja	next_directive
504
	cmp	cl,al
505
	jne	next_directive
506
	repe	cmps byte [esi],[edi]
507
	jb	no_directive
508
	je	directive_ok
509
      next_directive:
109 heavyiron 510
	mov	edi,ebx
157 heavyiron 511
	add	edi,2
512
	jmp	scan_directives
513
      no_directive:
109 heavyiron 514
	mov	esi,edx
157 heavyiron 515
	mov	ecx,ebp
516
	stc
517
	ret
518
      directive_ok:
109 heavyiron 519
	lea	esi,[edx+ebp]
157 heavyiron 520
	movzx	eax,word [ebx]
521
	add	eax,preprocessor
522
	clc
523
	ret
524
109 heavyiron 525
 
526
 
31 halyavin 527
	mov	eax,esp
157 heavyiron 528
	sub	eax,100h
529
	jc	stack_overflow
530
	cmp	eax,[stack_limit]
531
	jb	stack_overflow
532
	push	ecx esi
533
      preprocess_current_line:
31 halyavin 534
	mov	esi,[current_line]
157 heavyiron 535
	add	esi,16
536
	cmp	word [esi],3Bh
537
	jne	line_start_ok
538
	add	esi,2
539
      line_start_ok:
31 halyavin 540
	test	[macro_status],0F0h
157 heavyiron 541
	jnz	macro_preprocessing
542
	cmp	byte [esi],1Ah
543
	jne	not_fix_constant
544
	movzx	edx,byte [esi+1]
545
	lea	edx,[esi+2+edx]
546
	cmp	word [edx],031Ah
547
	jne	not_fix_constant
548
	mov	ebx,characters
549
	movzx	eax,byte [edx+2]
550
	xlat	byte [ebx]
551
	ror	eax,8
552
	mov	al,[edx+3]
553
	xlat	byte [ebx]
554
	ror	eax,8
555
	mov	al,[edx+4]
556
	xlat	byte [ebx]
557
	ror	eax,16
558
	cmp	eax,'fix'
559
	je	define_fix_constant
560
      not_fix_constant:
31 halyavin 561
	call	process_fix_constants
157 heavyiron 562
	jmp	initial_preprocessing_ok
563
      macro_preprocessing:
31 halyavin 564
	call	process_macro_operators
157 heavyiron 565
      initial_preprocessing_ok:
31 halyavin 566
	mov	esi,[current_line]
157 heavyiron 567
	add	esi,16
568
	mov	al,[macro_status]
569
	test	al,2
570
	jnz	skip_macro_block
571
	test	al,1
572
	jnz	find_macro_block
573
      preprocess_instruction:
31 halyavin 574
	mov	[current_offset],esi
157 heavyiron 575
	lods	byte [esi]
576
	movzx	ecx,byte [esi]
577
	inc	esi
578
	cmp	al,1Ah
579
	jne	not_preprocessor_symbol
580
	cmp	cl,3
581
	jb	not_preprocessor_directive
582
	push	edi
583
	mov	edi,preprocessor_directives
584
	call	get_directive
585
	pop	edi
586
	jc	not_preprocessor_directive
587
	mov	byte [edx-2],3Bh
588
	jmp	near eax
589
      not_preprocessor_directive:
31 halyavin 590
	xor	ch,ch
157 heavyiron 591
	call	get_preprocessor_symbol
592
	jc	not_macro
593
	mov	byte [ebx-2],3Bh
594
	mov	[struc_name],0
595
	jmp	use_macro
596
      not_macro:
31 halyavin 597
	mov	[struc_name],esi
157 heavyiron 598
	add	esi,ecx
599
	lods	byte [esi]
600
	cmp	al,':'
601
	je	preprocess_label
602
	cmp	al,1Ah
603
	jne	not_preprocessor_symbol
604
	lods	byte [esi]
605
	cmp	al,3
606
	jne	not_symbolic_constant
607
	mov	ebx,characters
608
	movzx	eax,byte [esi]
609
	xlat	byte [ebx]
610
	ror	eax,8
611
	mov	al,[esi+1]
612
	xlat	byte [ebx]
613
	ror	eax,8
614
	mov	al,[esi+2]
615
	xlat	byte [ebx]
616
	ror	eax,16
617
	cmp	eax,'equ'
618
	je	define_equ_constant
619
	mov	al,3
620
      not_symbolic_constant:
31 halyavin 621
	mov	ch,1
157 heavyiron 622
	mov	cl,al
623
	call	get_preprocessor_symbol
624
	jc	not_preprocessor_symbol
625
	push	edx esi
626
	mov	esi,[struc_name]
627
	mov	[struc_label],esi
628
	sub	[struc_label],2
629
	mov	cl,[esi-1]
630
	mov	ch,10b
631
	call	get_preprocessor_symbol
632
	jc	struc_name_ok
633
	mov	ecx,[edx+12]
634
	add	ecx,3
635
	lea	ebx,[edi+ecx]
636
	mov	ecx,edi
637
	sub	ecx,[struc_label]
638
	lea	esi,[edi-1]
639
	lea	edi,[ebx-1]
640
	std
641
	rep	movs byte [edi],[esi]
642
	cld
643
	mov	edi,[struc_label]
644
	mov	esi,[edx+8]
645
	mov	ecx,[edx+12]
646
	add	[struc_name],ecx
647
	add	[struc_name],3
648
	call	move_data
649
	mov	al,3Ah
650
	stos	byte [edi]
651
	mov	ax,3Bh
652
	stos	word [edi]
653
	mov	edi,ebx
654
	pop	esi
655
	add	esi,[edx+12]
656
	add	esi,3
657
	pop	edx
658
	jmp	use_macro
659
      struc_name_ok:
31 halyavin 660
	mov	edx,[struc_name]
157 heavyiron 661
	movzx	eax,byte [edx-1]
662
	add	edx,eax
663
	mov	al,3Ah
664
	mov	[edx],al
665
	inc	al
666
	xchg	al,[edx+1]
667
	dec	al
668
	mov	[edx+2],al
669
	pop	esi edx
670
	jmp	use_macro
671
      preprocess_label:
31 halyavin 672
	dec	esi
157 heavyiron 673
	sub	esi,ecx
674
	lea	ebp,[esi-2]
675
	mov	ch,10b
676
	call	get_preprocessor_symbol
677
	jnc	symbolic_constant_in_label
678
	lea	esi,[esi+ecx+1]
679
	jmp	preprocess_instruction
680
      symbolic_constant_in_label:
31 halyavin 681
	mov	ebx,[edx+8]
157 heavyiron 682
	mov	ecx,[edx+12]
683
	add	ecx,ebx
684
      check_for_broken_label:
31 halyavin 685
	cmp	ebx,ecx
157 heavyiron 686
	je	label_broken
687
	cmp	byte [ebx],1Ah
688
	jne	label_broken
689
	movzx	eax,byte [ebx+1]
690
	lea	ebx,[ebx+2+eax]
691
	cmp	ebx,ecx
692
	je	label_constant_ok
693
	cmp	byte [ebx],':'
694
	jne	label_broken
695
	inc	ebx
696
	jmp	check_for_broken_label
697
      label_broken:
31 halyavin 698
	push	line_preprocessed
157 heavyiron 699
	jmp	replace_symbolic_constant
700
      label_constant_ok:
31 halyavin 701
	mov	ecx,edi
157 heavyiron 702
	sub	ecx,esi
703
	mov	edi,[edx+12]
704
	add	edi,ebp
705
	push	edi
706
	lea	eax,[edi+ecx]
707
	push	eax
708
	cmp	esi,edi
709
	je	replace_label
710
	jb	move_rest_of_line_up
711
	rep	movs byte [edi],[esi]
712
	jmp	replace_label
713
      move_rest_of_line_up:
31 halyavin 714
	lea	esi,[esi+ecx-1]
157 heavyiron 715
	lea	edi,[edi+ecx-1]
716
	std
717
	rep	movs byte [edi],[esi]
718
	cld
719
      replace_label:
31 halyavin 720
	mov	ecx,[edx+12]
157 heavyiron 721
	mov	edi,[esp+4]
722
	sub	edi,ecx
723
	mov	esi,[edx+8]
724
	rep	movs byte [edi],[esi]
725
	pop	edi esi
726
	inc	esi
727
	jmp	preprocess_instruction
728
      not_preprocessor_symbol:
31 halyavin 729
	mov	esi,[current_offset]
157 heavyiron 730
	call	process_equ_constants
731
      line_preprocessed:
31 halyavin 732
	pop	esi ecx
157 heavyiron 733
	ret
734
31 halyavin 735
 
736
	push	ebp edi esi
157 heavyiron 737
	mov	ebp,ecx
738
	shl	ebp,22
739
	movzx	ecx,cl
740
	mov	ebx,hash_tree
741
	mov	edi,10
742
      follow_hashes_roots:
31 halyavin 743
	mov	edx,[ebx]
157 heavyiron 744
	or	edx,edx
745
	jz	preprocessor_symbol_not_found
746
	xor	eax,eax
747
	shl	ebp,1
748
	adc	eax,0
749
	lea	ebx,[edx+eax*4]
750
	dec	edi
751
	jnz	follow_hashes_roots
752
	mov	edi,ebx
753
	call	calculate_hash
754
	mov	ebp,eax
755
	and	ebp,3FFh
756
	shl	ebp,10
757
	xor	ebp,eax
758
	mov	ebx,edi
759
	mov	edi,22
760
      follow_hashes_tree:
31 halyavin 761
	mov	edx,[ebx]
157 heavyiron 762
	or	edx,edx
763
	jz	preprocessor_symbol_not_found
764
	xor	eax,eax
765
	shl	ebp,1
766
	adc	eax,0
767
	lea	ebx,[edx+eax*4]
768
	dec	edi
769
	jnz	follow_hashes_tree
770
	mov	al,cl
771
	mov	edx,[ebx]
772
	or	edx,edx
773
	jz	preprocessor_symbol_not_found
774
      compare_with_preprocessor_symbol:
31 halyavin 775
	mov	edi,[edx+4]
157 heavyiron 776
	cmp	edi,1
777
	jbe	next_equal_hash
778
	repe	cmps byte [esi],[edi]
779
	je	preprocessor_symbol_found
780
	mov	cl,al
781
	mov	esi,[esp]
782
      next_equal_hash:
31 halyavin 783
	mov	edx,[edx]
157 heavyiron 784
	or	edx,edx
785
	jnz	compare_with_preprocessor_symbol
786
      preprocessor_symbol_not_found:
31 halyavin 787
	pop	esi edi ebp
157 heavyiron 788
	stc
789
	ret
790
      preprocessor_symbol_found:
31 halyavin 791
	pop	ebx edi ebp
157 heavyiron 792
	clc
793
	ret
794
      calculate_hash:
31 halyavin 795
	xor	ebx,ebx
157 heavyiron 796
	mov	eax,2166136261
797
	mov	ebp,16777619
798
      fnv1a_hash:
31 halyavin 799
	xor	al,[esi+ebx]
157 heavyiron 800
	mul	ebp
801
	inc	bl
802
	cmp	bl,cl
803
	jb	fnv1a_hash
804
	ret
805
add_preprocessor_symbol:
31 halyavin 806
	push	edi esi
157 heavyiron 807
872 heavyiron 808
 
809
	call	get_directive
810
	jnc	reserved_word_used_as_symbol
811
812
 
157 heavyiron 813
	mov	ebp,eax
814
	and	ebp,3FFh
815
	shr	eax,10
816
	xor	ebp,eax
817
	shl	ecx,22
818
	or	ebp,ecx
819
	mov	ebx,hash_tree
820
	mov	ecx,32
821
      find_leave_for_symbol:
31 halyavin 822
	mov	edx,[ebx]
157 heavyiron 823
	or	edx,edx
824
	jz	extend_hashes_tree
825
	xor	eax,eax
826
	rol	ebp,1
827
	adc	eax,0
828
	lea	ebx,[edx+eax*4]
829
	dec	ecx
830
	jnz	find_leave_for_symbol
831
	mov	edx,[ebx]
832
	or	edx,edx
833
	jz	add_symbol_entry
834
	shr	ebp,30
835
	cmp	ebp,11b
836
	je	reuse_symbol_entry
837
	cmp	dword [edx+4],0
838
	jne	add_symbol_entry
839
      find_entry_to_reuse:
31 halyavin 840
	mov	edi,[edx]
157 heavyiron 841
	or	edi,edi
842
	jz	reuse_symbol_entry
843
	cmp	dword [edi+4],0
844
	jne	reuse_symbol_entry
845
	mov	edx,edi
846
	jmp	find_entry_to_reuse
847
      add_symbol_entry:
31 halyavin 848
	mov	eax,edx
157 heavyiron 849
	mov	edx,[labels_list]
850
	sub	edx,16
851
	cmp	edx,[free_additional_memory]
852
	jb	out_of_memory
853
	mov	[labels_list],edx
854
	mov	[edx],eax
855
	mov	[ebx],edx
856
      reuse_symbol_entry:
31 halyavin 857
	pop	esi edi
157 heavyiron 858
	mov	[edx+4],esi
859
	ret
860
      extend_hashes_tree:
31 halyavin 861
	mov	edx,[labels_list]
157 heavyiron 862
	sub	edx,8
863
	cmp	edx,[free_additional_memory]
864
	jb	out_of_memory
865
	mov	[labels_list],edx
866
	xor	eax,eax
867
	mov	[edx],eax
868
	mov	[edx+4],eax
869
	shl	ebp,1
870
	adc	eax,0
871
	mov	[ebx],edx
872
	lea	ebx,[edx+eax*4]
873
	dec	ecx
874
	jnz	extend_hashes_tree
875
	mov	edx,[labels_list]
876
	sub	edx,16
877
	cmp	edx,[free_additional_memory]
878
	jb	out_of_memory
879
	mov	[labels_list],edx
880
	mov	dword [edx],0
881
	mov	[ebx],edx
882
	pop	esi edi
883
	mov	[edx+4],esi
884
	ret
885
31 halyavin 886
 
887
	add	edx,5
157 heavyiron 888
	add	esi,2
889
	push	edx esi
890
	mov	esi,edx
891
	call	skip_parameters
892
	xchg	esi,[esp]
893
	mov	ch,11b
894
	jmp	define_preprocessor_constant
895
define_equ_constant:
31 halyavin 896
	add	esi,3
157 heavyiron 897
	push	esi
898
	call	process_equ_constants
899
	push	esi
900
	mov	esi,[struc_name]
901
	mov	ch,10b
902
      define_preprocessor_constant:
109 heavyiron 903
	mov	byte [esi-2],3Bh
157 heavyiron 904
	mov	cl,[esi-1]
905
	call	add_preprocessor_symbol
906
	pop	esi ebx
907
	mov	ecx,edi
908
	dec	ecx
909
	sub	ecx,ebx
910
	mov	[edx+8],ebx
911
	mov	[edx+12],ecx
912
	jmp	line_preprocessed
913
define_symbolic_constant:
109 heavyiron 914
	lods	byte [esi]
157 heavyiron 915
	cmp	al,1Ah
916
	jne	invalid_name
917
	lods	byte [esi]
918
	mov	cl,al
919
	mov	ch,10b
920
	call	add_preprocessor_symbol
921
	movzx	eax,byte [esi-1]
922
	add	esi,eax
923
	push	esi edx
924
	call	skip_parameters
925
	pop	edx ebx
926
	lea	ecx,[esi-1]
927
	sub	ecx,ebx
928
	mov	[edx+8],ebx
929
	mov	[edx+12],ecx
930
	jmp	line_preprocessed
931
      skip_parameters:
109 heavyiron 932
	lods	byte [esi]
157 heavyiron 933
	or	al,al
934
	jz	parameters_skipped
935
	cmp	al,'{'
936
	je	parameters_skipped
937
	cmp	al,22h
938
	je	skip_quoted_parameter
939
	cmp	al,1Ah
940
	jne	skip_parameters
941
	lods	byte [esi]
942
	movzx	eax,al
943
	add	esi,eax
944
	jmp	skip_parameters
945
      skip_quoted_parameter:
109 heavyiron 946
	lods	dword [esi]
157 heavyiron 947
	add	esi,eax
948
	jmp	skip_parameters
949
      parameters_skipped:
109 heavyiron 950
	ret
157 heavyiron 951
109 heavyiron 952
 
31 halyavin 953
	mov	ch,1
157 heavyiron 954
	jmp	make_macro
955
define_macro:
31 halyavin 956
	xor	ch,ch
157 heavyiron 957
      make_macro:
31 halyavin 958
	lods	byte [esi]
157 heavyiron 959
	cmp	al,1Ah
960
	jne	invalid_name
961
	lods	byte [esi]
962
	mov	cl,al
963
	call	add_preprocessor_symbol
964
	mov	eax,[current_line]
965
	mov	[edx+12],eax
966
	movzx	eax,byte [esi-1]
967
	add	esi,eax
968
	mov	[edx+8],esi
969
	mov	al,[macro_status]
970
	and	al,0F0h
971
	or	al,1
972
	mov	[macro_status],al
973
	mov	eax,[current_line]
974
	mov	[error_line],eax
975
	xor	bl,bl
976
	lods	byte [esi]
977
	or	al,al
978
	jz	line_preprocessed
979
	cmp	al,'{'
980
	je	found_macro_block
981
	dec	esi
982
      skip_macro_arguments:
31 halyavin 983
	lods	byte [esi]
157 heavyiron 984
	cmp	al,1Ah
985
	je	skip_macro_argument
986
	cmp	al,'['
987
	jne	invalid_macro_arguments
988
	xor	bl,-1
989
	jz	invalid_macro_arguments
990
	lods	byte [esi]
991
	cmp	al,1Ah
992
	jne	invalid_macro_arguments
993
      skip_macro_argument:
31 halyavin 994
	movzx	eax,byte [esi]
157 heavyiron 995
	inc	esi
996
	add	esi,eax
997
	lods	byte [esi]
998
	cmp	al,'*'
999
	jne	macro_argument_end
1000
	lods	byte [esi]
1001
      macro_argument_end:
31 halyavin 1002
	cmp	al,','
157 heavyiron 1003
	je	skip_macro_arguments
1004
	cmp	al,']'
1005
	jne	end_macro_arguments
1006
	lods	byte [esi]
1007
	not	bl
1008
      end_macro_arguments:
31 halyavin 1009
	or	bl,bl
157 heavyiron 1010
	jnz	invalid_macro_arguments
1011
	or	al,al
1012
	jz	line_preprocessed
1013
	cmp	al,'{'
1014
	je	found_macro_block
1015
	jmp	invalid_macro_arguments
1016
      find_macro_block:
31 halyavin 1017
	add	esi,2
157 heavyiron 1018
	lods	byte [esi]
1019
	or	al,al
1020
	jz	line_preprocessed
1021
	cmp	al,'{'
1022
	jne	unexpected_characters
1023
      found_macro_block:
31 halyavin 1024
	or	[macro_status],2
157 heavyiron 1025
      skip_macro_block:
31 halyavin 1026
	lods	byte [esi]
157 heavyiron 1027
	cmp	al,1Ah
1028
	je	skip_macro_symbol
1029
	cmp	al,3Bh
1030
	je	skip_macro_symbol
1031
	cmp	al,22h
1032
	je	skip_macro_string
1033
	or	al,al
1034
	jz	line_preprocessed
1035
	cmp	al,'}'
1036
	jne	skip_macro_block
1037
	mov	al,[macro_status]
1038
	and	[macro_status],0F0h
1039
	test	al,8
1040
	jnz	use_instant_macro
1041
	cmp	byte [esi],0
1042
	je	line_preprocessed
1043
	mov	ecx,edi
1044
	sub	ecx,esi
1045
	mov	edx,esi
1046
	lea	esi,[esi+ecx-1]
1047
	lea	edi,[edi+1+16]
1048
	mov	ebx,edi
1049
	dec	edi
1050
	std
1051
	rep	movs byte [edi],[esi]
1052
	cld
1053
	mov	edi,edx
1054
	xor	al,al
1055
	stos	byte [edi]
1056
	mov	esi,[current_line]
1057
	mov	[current_line],edi
1058
	mov	ecx,4
1059
	rep	movs dword [edi],[esi]
1060
	mov	edi,ebx
1061
	jmp	initial_preprocessing_ok
1062
      skip_macro_symbol:
31 halyavin 1063
	movzx	eax,byte [esi]
157 heavyiron 1064
	inc	esi
1065
	add	esi,eax
1066
	jmp	skip_macro_block
1067
      skip_macro_string:
31 halyavin 1068
	lods	dword [esi]
157 heavyiron 1069
	add	esi,eax
1070
	jmp	skip_macro_block
1071
rept_directive:
31 halyavin 1072
	mov	[base_code],0
157 heavyiron 1073
	jmp	define_instant_macro
1074
irp_directive:
31 halyavin 1075
	mov	[base_code],1
157 heavyiron 1076
	jmp	define_instant_macro
1077
irps_directive:
31 halyavin 1078
	mov	[base_code],2
157 heavyiron 1079
	jmp	define_instant_macro
1080
match_directive:
31 halyavin 1081
	mov	[base_code],10h
157 heavyiron 1082
define_instant_macro:
31 halyavin 1083
	mov	al,[macro_status]
157 heavyiron 1084
	and	al,0F0h
1085
	or	al,8+1
1086
	mov	[macro_status],al
1087
	mov	eax,[current_line]
1088
	mov	[error_line],eax
1089
	mov	[instant_macro_start],esi
1090
	cmp	[base_code],10h
1091
	je	prepare_match
1092
	call	skip_parameters
1093
      instant_macro_parameters_skipped:
109 heavyiron 1094
	dec	esi
157 heavyiron 1095
	mov	[parameters_end],esi
1096
	lods	byte [esi]
1097
	cmp	al,'{'
1098
	je	found_macro_block
1099
	or	al,al
1100
	jnz	invalid_macro_arguments
1101
	jmp	line_preprocessed
1102
prepare_match:
31 halyavin 1103
	call	skip_pattern
157 heavyiron 1104
	mov	[value_type],80h+10b
1105
	call	process_symbolic_constants
1106
	jmp	instant_macro_parameters_skipped
1107
      skip_pattern:
31 halyavin 1108
	lods	byte [esi]
157 heavyiron 1109
	or	al,al
1110
	jz	invalid_macro_arguments
1111
	cmp	al,','
1112
	je	pattern_skipped
1113
	cmp	al,22h
1114
	je	skip_quoted_string_in_pattern
1115
	cmp	al,1Ah
1116
	je	skip_symbol_in_pattern
1117
	cmp	al,'='
1118
	jne	skip_pattern
1119
	mov	al,[esi]
1120
	cmp	al,1Ah
1121
	je	skip_pattern
1122
	cmp	al,22h
1123
	je	skip_pattern
1124
	inc	esi
1125
	jmp	skip_pattern
1126
      skip_symbol_in_pattern:
31 halyavin 1127
	lods	byte [esi]
157 heavyiron 1128
	movzx	eax,al
1129
	add	esi,eax
1130
	jmp	skip_pattern
1131
      skip_quoted_string_in_pattern:
31 halyavin 1132
	lods	dword [esi]
157 heavyiron 1133
	add	esi,eax
1134
	jmp	skip_pattern
1135
      pattern_skipped:
31 halyavin 1136
	ret
157 heavyiron 1137
31 halyavin 1138
 
1139
	xor	ch,ch
157 heavyiron 1140
	jmp	restore_preprocessor_symbol
1141
purge_struc:
31 halyavin 1142
	mov	ch,1
157 heavyiron 1143
	jmp	restore_preprocessor_symbol
1144
restore_equ_constant:
31 halyavin 1145
	mov	ch,10b
157 heavyiron 1146
      restore_preprocessor_symbol:
31 halyavin 1147
	push	ecx
157 heavyiron 1148
	lods	byte [esi]
1149
	cmp	al,1Ah
1150
	jne	invalid_name
1151
	lods	byte [esi]
1152
	mov	cl,al
1153
	call	get_preprocessor_symbol
1154
	jc	no_symbol_to_restore
1155
	mov	dword [edx+4],0
1156
	jmp	symbol_restored
1157
      no_symbol_to_restore:
31 halyavin 1158
	add	esi,ecx
157 heavyiron 1159
      symbol_restored:
31 halyavin 1160
	pop	ecx
157 heavyiron 1161
	lods	byte [esi]
1162
	cmp	al,','
1163
	je	restore_preprocessor_symbol
1164
	or	al,al
1165
	jnz	extra_characters_on_line
1166
	jmp	line_preprocessed
1167
31 halyavin 1168
 
1169
	mov	[value_type],11b
157 heavyiron 1170
	jmp	process_symbolic_constants
1171
process_equ_constants:
31 halyavin 1172
	mov	[value_type],10b
157 heavyiron 1173
      process_symbolic_constants:
31 halyavin 1174
	mov	ebp,esi
157 heavyiron 1175
	lods	byte [esi]
1176
	cmp	al,1Ah
1177
	je	check_symbol
1178
	cmp	al,22h
1179
	je	ignore_string
1180
	cmp	al,'{'
1181
	je	check_brace
1182
	or	al,al
1183
	jnz	process_symbolic_constants
1184
	ret
1185
      ignore_string:
31 halyavin 1186
	lods	dword [esi]
157 heavyiron 1187
	add	esi,eax
1188
	jmp	process_symbolic_constants
1189
      check_brace:
31 halyavin 1190
	test	[value_type],80h
157 heavyiron 1191
	jz	process_symbolic_constants
1192
	ret
1193
      no_replacing:
31 halyavin 1194
	movzx	ecx,byte [esi-1]
157 heavyiron 1195
	add	esi,ecx
1196
	jmp	process_symbolic_constants
1197
      check_symbol:
31 halyavin 1198
	mov	cl,[esi]
157 heavyiron 1199
	inc	esi
1200
	mov	ch,[value_type]
1201
	call	get_preprocessor_symbol
1202
	jc	no_replacing
1203
	mov	[current_section],edi
1204
      replace_symbolic_constant:
31 halyavin 1205
	mov	ecx,[edx+12]
157 heavyiron 1206
	mov	edx,[edx+8]
1207
	xchg	esi,edx
1208
	call	move_data
1209
	mov	esi,edx
1210
      process_after_replaced:
31 halyavin 1211
	lods	byte [esi]
157 heavyiron 1212
	cmp	al,1Ah
1213
	je	symbol_after_replaced
1214
	stos	byte [edi]
1215
	cmp	al,22h
1216
	je	string_after_replaced
1217
	cmp	al,'{'
1218
	je	brace_after_replaced
1219
	or	al,al
1220
	jnz	process_after_replaced
1221
	mov	ecx,edi
1222
	sub	ecx,esi
1223
	mov	edi,ebp
1224
	call	move_data
1225
	mov	esi,edi
1226
	ret
1227
      move_data:
31 halyavin 1228
	lea	eax,[edi+ecx]
157 heavyiron 1229
	cmp	eax,[memory_end]
1230
	jae	out_of_memory
1231
	shr	ecx,1
1232
	jnc	movsb_ok
1233
	movs	byte [edi],[esi]
1234
      movsb_ok:
31 halyavin 1235
	shr	ecx,1
157 heavyiron 1236
	jnc	movsw_ok
1237
	movs	word [edi],[esi]
1238
      movsw_ok:
31 halyavin 1239
	rep	movs dword [edi],[esi]
157 heavyiron 1240
	ret
1241
      string_after_replaced:
31 halyavin 1242
	lods	dword [esi]
157 heavyiron 1243
	stos	dword [edi]
1244
	mov	ecx,eax
1245
	call	move_data
1246
	jmp	process_after_replaced
1247
      brace_after_replaced:
31 halyavin 1248
	test	[value_type],80h
157 heavyiron 1249
	jz	process_after_replaced
1250
	mov	edx,edi
1251
	mov	ecx,[current_section]
1252
	sub	edx,ecx
1253
	sub	ecx,esi
1254
	rep	movs byte [edi],[esi]
1255
	mov	ecx,edi
1256
	sub	ecx,esi
1257
	mov	edi,ebp
1258
	call	move_data
1259
	lea	esi,[ebp+edx]
1260
	ret
1261
      symbol_after_replaced:
31 halyavin 1262
	mov	cl,[esi]
157 heavyiron 1263
	inc	esi
1264
	mov	ch,[value_type]
1265
	call	get_preprocessor_symbol
1266
	jnc	replace_symbolic_constant
1267
	movzx	ecx,byte [esi-1]
1268
	mov	al,1Ah
1269
	mov	ah,cl
1270
	stos	word [edi]
1271
	call	move_data
1272
	jmp	process_after_replaced
1273
process_macro_operators:
31 halyavin 1274
	xor	dl,dl
157 heavyiron 1275
	mov	ebp,edi
1276
      before_macro_operators:
31 halyavin 1277
	mov	edi,esi
157 heavyiron 1278
	lods	byte [esi]
1279
	cmp	al,'`'
1280
	je	symbol_conversion
1281
	cmp	al,'#'
1282
	je	concatenation
1283
	cmp	al,1Ah
1284
	je	symbol_before_macro_operators
1285
	cmp	al,3Bh
1286
	je	no_more_macro_operators
1287
	cmp	al,22h
1288
	je	string_before_macro_operators
1289
	xor	dl,dl
1290
	or	al,al
1291
	jnz	before_macro_operators
1292
	mov	edi,esi
1293
	ret
1294
      no_more_macro_operators:
31 halyavin 1295
	mov	edi,ebp
157 heavyiron 1296
	ret
1297
      symbol_before_macro_operators:
31 halyavin 1298
	mov	dl,1Ah
157 heavyiron 1299
	mov	ebx,esi
1300
	lods	byte [esi]
1301
	movzx	ecx,al
1302
	jecxz	symbol_before_macro_operators_ok
1303
	mov	edi,esi
1304
	cmp	byte [esi],'\'
1305
	je	escaped_symbol
1306
      symbol_before_macro_operators_ok:
31 halyavin 1307
	add	esi,ecx
157 heavyiron 1308
	jmp	before_macro_operators
1309
      string_before_macro_operators:
31 halyavin 1310
	mov	dl,22h
157 heavyiron 1311
	mov	ebx,esi
1312
	lods	dword [esi]
1313
	add	esi,eax
1314
	jmp	before_macro_operators
1315
      escaped_symbol:
31 halyavin 1316
	dec	byte [edi-1]
157 heavyiron 1317
	dec	ecx
1318
	inc	esi
1319
	cmp	ecx,1
1320
	rep	movs byte [edi],[esi]
1321
	jne	after_macro_operators
1322
	mov	al,[esi-1]
1323
	mov	ecx,ebx
1324
	mov	ebx,characters
1325
	xlat	byte [ebx]
1326
	mov	ebx,ecx
1327
	or	al,al
1328
	jnz	after_macro_operators
1329
	sub	edi,3
1330
	mov	al,[esi-1]
1331
	stos	byte [edi]
1332
	xor	dl,dl
1333
	jmp	after_macro_operators
1334
      reduce_symbol_conversion:
109 heavyiron 1335
	inc	esi
157 heavyiron 1336
      symbol_conversion:
31 halyavin 1337
	mov	edx,esi
157 heavyiron 1338
	mov	al,[esi]
1339
	cmp	al,1Ah
1340
	jne	symbol_character_conversion
1341
	lods	word [esi]
1342
	movzx	ecx,ah
1343
	lea	ebx,[edi+3]
1344
	jecxz	convert_to_quoted_string
242 heavyiron 1345
	cmp	byte [esi],'\'
1346
	jne	convert_to_quoted_string
1347
	inc	esi
1348
	dec	ecx
1349
	dec	ebx
1350
	jmp	convert_to_quoted_string
157 heavyiron 1351
      symbol_character_conversion:
109 heavyiron 1352
	cmp	al,22h
157 heavyiron 1353
	je	after_macro_operators
1354
	cmp	al,'`'
1355
	je	reduce_symbol_conversion
1356
	lea	ebx,[edi+5]
1357
	xor	ecx,ecx
1358
	or	al,al
1359
	jz	convert_to_quoted_string
1360
	cmp	al,'#'
1361
	je	convert_to_quoted_string
1362
	inc	ecx
1363
      convert_to_quoted_string:
109 heavyiron 1364
	sub	ebx,edx
157 heavyiron 1365
	ja	shift_line_data
1366
	mov	al,22h
1367
	mov	dl,al
1368
	stos	byte [edi]
1369
	mov	ebx,edi
1370
	mov	eax,ecx
1371
	stos	dword [edi]
1372
	rep	movs byte [edi],[esi]
1373
	cmp	edi,esi
1374
	je	before_macro_operators
1375
	jmp	after_macro_operators
1376
      shift_line_data:
31 halyavin 1377
	push	ecx
157 heavyiron 1378
	mov	edx,esi
1379
	lea	esi,[ebp-1]
1380
	add	ebp,ebx
1381
	lea	edi,[ebp-1]
1382
	lea	ecx,[esi+1]
1383
	sub	ecx,edx
1384
	std
1385
	rep	movs byte [edi],[esi]
1386
	cld
1387
	pop	eax
1388
	sub	edi,3
1389
	mov	dl,22h
1390
	mov	[edi-1],dl
1391
	mov	ebx,edi
1392
	mov	[edi],eax
1393
	lea	esi,[edi+4+eax]
1394
	jmp	before_macro_operators
1395
      concatenation:
31 halyavin 1396
	cmp	dl,1Ah
157 heavyiron 1397
	je	symbol_concatenation
1398
	cmp	dl,22h
1399
	je	string_concatenation
1400
      no_concatenation:
31 halyavin 1401
	cmp	esi,edi
157 heavyiron 1402
	je	before_macro_operators
1403
	jmp	after_macro_operators
1404
      symbol_concatenation:
31 halyavin 1405
	cmp	byte [esi],1Ah
157 heavyiron 1406
	jne	no_concatenation
1407
	inc	esi
1408
	lods	byte [esi]
1409
	movzx	ecx,al
1410
	jecxz	do_symbol_concatenation
1411
	cmp	byte [esi],'\'
1412
	je	concatenate_escaped_symbol
242 heavyiron 1413
      do_symbol_concatenation:
31 halyavin 1414
	add	[ebx],cl
242 heavyiron 1415
	jc	name_too_long
157 heavyiron 1416
	rep	movs byte [edi],[esi]
1417
	jmp	after_macro_operators
1418
      concatenate_escaped_symbol:
242 heavyiron 1419
	inc	esi
1420
	dec	ecx
1421
	jz	do_symbol_concatenation
1422
	movzx	eax,byte [esi]
1423
	cmp	byte [characters+eax],0
1424
	jne	do_symbol_concatenation
1425
	sub	esi,3
1426
	jmp	no_concatenation
1427
      string_concatenation:
31 halyavin 1428
	cmp	byte [esi],22h
157 heavyiron 1429
	je	do_string_concatenation
1430
	cmp	byte [esi],'`'
1431
	jne	no_concatenation
1432
      concatenate_converted_symbol:
109 heavyiron 1433
	inc	esi
157 heavyiron 1434
	mov	al,[esi]
1435
	cmp	al,'`'
1436
	je	concatenate_converted_symbol
1437
	cmp	al,22h
1438
	je	do_string_concatenation
1439
	cmp	al,1Ah
1440
	jne	concatenate_converted_symbol_character
1441
	inc	esi
1442
	lods	byte [esi]
1443
	movzx	ecx,al
1444
	jecxz	finish_concatenating_converted_symbol
242 heavyiron 1445
	cmp	byte [esi],'\'
1446
	jne	finish_concatenating_converted_symbol
1447
	inc	esi
1448
	dec	ecx
1449
      finish_concatenating_converted_symbol:
1450
	add	[ebx],ecx
157 heavyiron 1451
	rep	movs byte [edi],[esi]
1452
	jmp	after_macro_operators
1453
      concatenate_converted_symbol_character:
109 heavyiron 1454
	or	al,al
157 heavyiron 1455
	jz	after_macro_operators
1456
	cmp	al,'#'
1457
	je	after_macro_operators
1458
	inc	dword [ebx]
1459
	movs	byte [edi],[esi]
1460
	jmp	after_macro_operators
1461
      do_string_concatenation:
31 halyavin 1462
	inc	esi
157 heavyiron 1463
	lods	dword [esi]
1464
	mov	ecx,eax
1465
	add	[ebx],eax
1466
	rep	movs byte [edi],[esi]
1467
      after_macro_operators:
31 halyavin 1468
	lods	byte [esi]
157 heavyiron 1469
	cmp	al,'`'
1470
	je	symbol_conversion
1471
	cmp	al,'#'
1472
	je	concatenation
1473
	stos	byte [edi]
1474
	cmp	al,1Ah
1475
	je	symbol_after_macro_operators
1476
	cmp	al,3Bh
1477
	je	no_more_macro_operators
1478
	cmp	al,22h
1479
	je	string_after_macro_operators
1480
	xor	dl,dl
1481
	or	al,al
1482
	jnz	after_macro_operators
1483
	ret
1484
      symbol_after_macro_operators:
31 halyavin 1485
	mov	dl,1Ah
157 heavyiron 1486
	mov	ebx,edi
1487
	lods	byte [esi]
1488
	stos	byte [edi]
1489
	movzx	ecx,al
1490
	jecxz	symbol_after_macro_operatorss_ok
1491
	cmp	byte [esi],'\'
1492
	je	escaped_symbol
1493
      symbol_after_macro_operatorss_ok:
31 halyavin 1494
	rep	movs byte [edi],[esi]
157 heavyiron 1495
	jmp	after_macro_operators
1496
      string_after_macro_operators:
31 halyavin 1497
	mov	dl,22h
157 heavyiron 1498
	mov	ebx,edi
1499
	lods	dword [esi]
1500
	stos	dword [edi]
1501
	mov	ecx,eax
1502
	rep	movs byte [edi],[esi]
1503
	jmp	after_macro_operators
1504
31 halyavin 1505
 
1506
	push	[free_additional_memory]
157 heavyiron 1507
	push	[macro_symbols]
1508
	mov	[macro_symbols],0
1509
	push	[counter_limit]
1510
	push	dword [edx+4]
1511
	mov	dword [edx+4],1
1512
	push	edx
1513
	mov	ebx,esi
1514
	mov	esi,[edx+8]
1515
	mov	eax,[edx+12]
1516
	mov	[macro_line],eax
1517
	mov	[counter_limit],0
1518
      process_macro_arguments:
31 halyavin 1519
	mov	al,[esi]
157 heavyiron 1520
	or	al,al
1521
	jz	arguments_end
1522
	cmp	al,'{'
1523
	je	arguments_end
1524
	inc	esi
1525
	cmp	al,'['
1526
	jne	get_macro_arguments
1527
	mov	ebp,esi
1528
	inc	esi
1529
	inc	[counter_limit]
1530
      get_macro_arguments:
31 halyavin 1531
	call	get_macro_argument
157 heavyiron 1532
	lods	byte [esi]
1533
	cmp	al,','
1534
	je	next_argument
1535
	cmp	al,']'
1536
	je	next_arguments_group
1537
	dec	esi
1538
	jmp	arguments_end
1539
      next_argument:
31 halyavin 1540
	cmp	byte [ebx],','
157 heavyiron 1541
	jne	process_macro_arguments
1542
	inc	ebx
1543
	jmp	process_macro_arguments
1544
      next_arguments_group:
31 halyavin 1545
	cmp	byte [ebx],','
157 heavyiron 1546
	jne	arguments_end
1547
	inc	ebx
1548
	inc	[counter_limit]
1549
	mov	esi,ebp
1550
	jmp	process_macro_arguments
1551
      get_macro_argument:
31 halyavin 1552
	lods	byte [esi]
157 heavyiron 1553
	movzx	ecx,al
1554
	mov	eax,[counter_limit]
1555
	call	add_macro_symbol
1556
	add	esi,ecx
1557
	xchg	esi,ebx
1558
	mov	[edx+12],esi
1559
	cmp	byte [esi],'<'
1560
	jne	simple_argument
1561
	inc	esi
1562
	mov	[edx+12],esi
1563
	mov	ecx,1
1564
      enclosed_argument:
31 halyavin 1565
	lods	byte [esi]
157 heavyiron 1566
	or	al,al
1567
	jz	invalid_macro_arguments
1568
	cmp	al,1Ah
1569
	je	enclosed_symbol
1570
	cmp	al,22h
1571
	je	enclosed_string
1572
	cmp	al,'>'
1573
	je	enclosed_argument_end
1574
	cmp	al,'<'
1575
	jne	enclosed_argument
1576
	inc	ecx
1577
	jmp	enclosed_argument
1578
      enclosed_symbol:
31 halyavin 1579
	movzx	eax,byte [esi]
157 heavyiron 1580
	inc	esi
1581
	add	esi,eax
1582
	jmp	enclosed_argument
1583
      enclosed_string:
31 halyavin 1584
	lods	dword [esi]
157 heavyiron 1585
	add	esi,eax
1586
	jmp	enclosed_argument
1587
      enclosed_argument_end:
31 halyavin 1588
	loop	enclosed_argument
157 heavyiron 1589
	mov	al,[esi]
1590
	or	al,al
1591
	jz	enclosed_argument_ok
1592
	cmp	al,','
1593
	jne	invalid_macro_arguments
1594
      enclosed_argument_ok:
31 halyavin 1595
	mov	eax,esi
157 heavyiron 1596
	sub	eax,[edx+12]
1597
	dec	eax
1598
	or	eax,80000000h
1599
	mov	[edx+8],eax
1600
	jmp	argument_value_ok
1601
      simple_argument:
31 halyavin 1602
	lods	byte [esi]
157 heavyiron 1603
	or	al,al
1604
	jz	argument_value_end
1605
	cmp	al,','
1606
	je	argument_value_end
1607
	cmp	al,22h
1608
	je	argument_string
1609
	cmp	al,1Ah
1610
	jne	simple_argument
1611
	movzx	eax,byte [esi]
1612
	inc	esi
1613
	add	esi,eax
1614
	jmp	simple_argument
1615
      argument_string:
31 halyavin 1616
	lods	dword [esi]
157 heavyiron 1617
	add	esi,eax
1618
	jmp	simple_argument
1619
      argument_value_end:
31 halyavin 1620
	dec	esi
157 heavyiron 1621
	mov	eax,esi
1622
	sub	eax,[edx+12]
1623
	mov	[edx+8],eax
1624
      argument_value_ok:
31 halyavin 1625
	xchg	esi,ebx
157 heavyiron 1626
	cmp	byte [esi],'*'
1627
	jne	macro_argument_ok
1628
	cmp	dword [edx+8],0
1629
	je	invalid_macro_arguments
1630
	inc	esi
1631
      macro_argument_ok:
31 halyavin 1632
	ret
157 heavyiron 1633
      arguments_end:
31 halyavin 1634
	cmp	byte [ebx],0
157 heavyiron 1635
	jne	invalid_macro_arguments
1636
	mov	eax,[esp+4]
1637
	dec	eax
1638
	call	process_macro
1639
	pop	edx
1640
	pop	dword [edx+4]
1641
	pop	[counter_limit]
1642
	pop	[macro_symbols]
1643
	pop	[free_additional_memory]
1644
	jmp	line_preprocessed
1645
use_instant_macro:
31 halyavin 1646
	push	edi [current_line] esi
157 heavyiron 1647
	mov	eax,[error_line]
1648
	mov	[current_line],eax
1649
	mov	[macro_line],eax
1650
	mov	esi,[instant_macro_start]
1651
	cmp	[base_code],10h
1652
	jae	do_match
1653
	cmp	[base_code],0
1654
	jne	do_irp
1655
	call	get_number
1656
	jc	invalid_value
1657
	or	ebp,ebp
1658
	jnz	invalid_value
1659
	cmp	dword [edi+4],0
1660
	jne	value_out_of_range
1661
	mov	eax,[edi]
1662
872 heavyiron 1663
 
157 heavyiron 1664
	jae	value_out_of_range
1665
	push	[free_additional_memory]
1666
	push	[macro_symbols]
1667
	mov	[macro_symbols],0
1668
	push	[counter_limit]
1669
	mov	[struc_name],0
1670
	mov	[counter_limit],eax
1671
	lods	byte [esi]
1672
	or	al,al
1673
	jz	rept_counters_ok
1674
	cmp	al,'{'
1675
	je	rept_counters_ok
1676
	cmp	al,1Ah
1677
	jne	invalid_macro_arguments
1678
      add_rept_counter:
31 halyavin 1679
	lods	byte [esi]
157 heavyiron 1680
	movzx	ecx,al
1681
	xor	eax,eax
1682
	call	add_macro_symbol
1683
	add	esi,ecx
1684
	xor	eax,eax
1685
	mov	dword [edx+12],eax
1686
	inc	eax
1687
	mov	dword [edx+8],eax
1688
	lods	byte [esi]
1689
	cmp	al,':'
1690
	jne	rept_counter_added
1691
	push	edx
1692
	call	get_number
1693
	jc	invalid_value
1694
	or	ebp,ebp
1695
	jnz	invalid_value
1696
	cmp	dword [edi+4],0
1697
	jne	value_out_of_range
1698
	mov	eax,[edi]
1699
	mov	edx,eax
1700
	add	edx,[counter_limit]
1701
	jc	value_out_of_range
1702
	pop	edx
1703
	mov	dword [edx+8],eax
1704
	lods	byte [esi]
1705
      rept_counter_added:
31 halyavin 1706
	cmp	al,','
157 heavyiron 1707
	jne	rept_counters_ok
1708
	lods	byte [esi]
1709
	cmp	al,1Ah
1710
	jne	invalid_macro_arguments
1711
	jmp	add_rept_counter
1712
      rept_counters_ok:
31 halyavin 1713
	dec	esi
157 heavyiron 1714
	cmp	[counter_limit],0
872 heavyiron 1715
	je	instant_macro_finish
1716
      instant_macro_parameters_ok:
31 halyavin 1717
	xor	eax,eax
157 heavyiron 1718
	call	process_macro
1719
      instant_macro_finish:
872 heavyiron 1720
	pop	[counter_limit]
157 heavyiron 1721
	pop	[macro_symbols]
1722
	pop	[free_additional_memory]
1723
      instant_macro_done:
31 halyavin 1724
	pop	ebx esi edx
157 heavyiron 1725
	cmp	byte [ebx],0
1726
	je	line_preprocessed
1727
	mov	[current_line],edi
1728
	mov	ecx,4
1729
	rep	movs dword [edi],[esi]
1730
	test	[macro_status],0Fh
1731
	jz	instant_macro_attached_line
1732
	mov	ax,3Bh
1733
	stos	word [edi]
1734
      instant_macro_attached_line:
31 halyavin 1735
	mov	esi,ebx
157 heavyiron 1736
	sub	edx,ebx
1737
	mov	ecx,edx
1738
	call	move_data
1739
	jmp	initial_preprocessing_ok
1740
do_irp:
31 halyavin 1741
	cmp	byte [esi],1Ah
157 heavyiron 1742
	jne	invalid_macro_arguments
1743
	movzx	eax,byte [esi+1]
1744
	lea	esi,[esi+2+eax]
1745
	lods	byte [esi]
1746
	cmp	[base_code],1
1747
	ja	irps_name_ok
1748
	cmp	al,'*'
1749
	jne	irp_name_ok
1750
	lods	byte [esi]
1751
      irp_name_ok:
31 halyavin 1752
	cmp	al,','
157 heavyiron 1753
	jne	invalid_macro_arguments
1754
	jmp	irp_parameters_start
1755
      irps_name_ok:
31 halyavin 1756
	cmp	al,','
157 heavyiron 1757
	jne	invalid_macro_arguments
1758
	mov	al,[esi]
1759
	or	al,al
1760
	jz	instant_macro_done
1761
	cmp	al,'{'
1762
	je	instant_macro_done
1763
      irp_parameters_start:
31 halyavin 1764
	xor	eax,eax
157 heavyiron 1765
	push	[free_additional_memory]
1766
	push	[macro_symbols]
1767
	mov	[macro_symbols],eax
1768
	push	[counter_limit]
1769
	mov	[counter_limit],eax
1770
	mov	[struc_name],eax
1771
	mov	ebx,esi
1772
	cmp	[base_code],1
1773
	ja	get_irps_parameter
1774
	mov	edx,[parameters_end]
1775
	mov	al,[edx]
1776
	push	eax
1777
	mov	byte [edx],0
1778
      get_irp_parameter:
31 halyavin 1779
	inc	[counter_limit]
157 heavyiron 1780
	mov	esi,[instant_macro_start]
1781
	inc	esi
1782
	call	get_macro_argument
1783
	cmp	byte [ebx],','
1784
	jne	irp_parameters_end
1785
	inc	ebx
1786
	jmp	get_irp_parameter
1787
      irp_parameters_end:
31 halyavin 1788
	mov	esi,ebx
157 heavyiron 1789
	pop	eax
1790
	mov	[esi],al
1791
	jmp	instant_macro_parameters_ok
1792
      get_irps_parameter:
31 halyavin 1793
	mov	esi,[instant_macro_start]
157 heavyiron 1794
	inc	esi
1795
	lods	byte [esi]
1796
	movzx	ecx,al
1797
	inc	[counter_limit]
1798
	mov	eax,[counter_limit]
1799
	call	add_macro_symbol
1800
	mov	[edx+12],ebx
1801
	cmp	byte [ebx],1Ah
1802
	je	irps_symbol
1803
	cmp	byte [ebx],22h
1804
	je	irps_quoted_string
1805
	mov	eax,1
1806
	jmp	irps_parameter_ok
1807
      irps_quoted_string:
31 halyavin 1808
	mov	eax,[ebx+1]
157 heavyiron 1809
	add	eax,1+4
1810
	jmp	irps_parameter_ok
1811
      irps_symbol:
31 halyavin 1812
	movzx	eax,byte [ebx+1]
157 heavyiron 1813
	add	eax,1+1
1814
      irps_parameter_ok:
31 halyavin 1815
	mov	[edx+8],eax
157 heavyiron 1816
	add	ebx,eax
1817
	cmp	byte [ebx],0
1818
	je	irps_parameters_end
1819
	cmp	byte [ebx],'{'
1820
	jne	get_irps_parameter
1821
      irps_parameters_end:
31 halyavin 1822
	mov	esi,ebx
157 heavyiron 1823
	jmp	instant_macro_parameters_ok
1824
do_match:
31 halyavin 1825
	mov	ebx,esi
157 heavyiron 1826
	call	skip_pattern
1827
	call	exact_match
1828
	mov	edx,edi
1829
	mov	al,[ebx]
1830
	cmp	al,1Ah
1831
	je	free_match
1832
	cmp	al,','
1833
	jne	instant_macro_done
1834
	cmp	esi,[parameters_end]
1835
	je	matched_pattern
1836
	jmp	instant_macro_done
1837
      free_match:
31 halyavin 1838
	add	edx,12
157 heavyiron 1839
	cmp	edx,[memory_end]
1840
	ja	out_of_memory
1841
	mov	[edx-12],ebx
1842
	mov	[edx-8],esi
1843
	call	skip_match_element
1844
	jc	try_different_matching
1845
	mov	[edx-4],esi
1846
	movzx	eax,byte [ebx+1]
1847
	lea	ebx,[ebx+2+eax]
1848
	cmp	byte [ebx],1Ah
1849
	je	free_match
1850
      find_exact_match:
31 halyavin 1851
	call	exact_match
157 heavyiron 1852
	cmp	esi,[parameters_end]
1853
	je	end_matching
1854
	cmp	byte [ebx],1Ah
1855
	je	free_match
1856
	mov	ebx,[edx-12]
1857
	movzx	eax,byte [ebx+1]
1858
	lea	ebx,[ebx+2+eax]
1859
	mov	esi,[edx-4]
1860
	jmp	match_more_elements
1861
      try_different_matching:
31 halyavin 1862
	sub	edx,12
157 heavyiron 1863
	cmp	edx,edi
1864
	je	instant_macro_done
1865
	mov	ebx,[edx-12]
1866
	movzx	eax,byte [ebx+1]
1867
	lea	ebx,[ebx+2+eax]
1868
	cmp	byte [ebx],1Ah
1869
	je	try_different_matching
1870
	mov	esi,[edx-4]
1871
      match_more_elements:
31 halyavin 1872
	call	skip_match_element
157 heavyiron 1873
	jc	try_different_matching
1874
	mov	[edx-4],esi
1875
	jmp	find_exact_match
1876
      skip_match_element:
31 halyavin 1877
	cmp	esi,[parameters_end]
157 heavyiron 1878
	je	cannot_match
1879
	mov	al,[esi]
1880
	cmp	al,1Ah
1881
	je	skip_match_symbol
1882
	cmp	al,22h
1883
	je	skip_match_quoted_string
1884
	add	esi,1
1885
	ret
1886
      skip_match_quoted_string:
31 halyavin 1887
	mov	eax,[esi+1]
157 heavyiron 1888
	add	esi,5
1889
	jmp	skip_match_ok
1890
      skip_match_symbol:
31 halyavin 1891
	movzx	eax,byte [esi+1]
157 heavyiron 1892
	add	esi,2
1893
      skip_match_ok:
31 halyavin 1894
	add	esi,eax
157 heavyiron 1895
	ret
1896
      cannot_match:
31 halyavin 1897
	stc
157 heavyiron 1898
	ret
1899
      exact_match:
31 halyavin 1900
	cmp	esi,[parameters_end]
157 heavyiron 1901
	je	exact_match_complete
1902
	mov	ah,[esi]
1903
	mov	al,[ebx]
1904
	cmp	al,','
1905
	je	exact_match_complete
1906
	cmp	al,1Ah
1907
	je	exact_match_complete
1908
	cmp	al,'='
1909
	je	match_verbatim
1910
	call	match_elements
1911
	je	exact_match
1912
      exact_match_complete:
31 halyavin 1913
	ret
157 heavyiron 1914
      match_verbatim:
31 halyavin 1915
	inc	ebx
157 heavyiron 1916
	call	match_elements
1917
	je	exact_match
1918
	dec	ebx
1919
	ret
1920
      match_elements:
31 halyavin 1921
	mov	al,[ebx]
157 heavyiron 1922
	cmp	al,1Ah
1923
	je	match_symbols
1924
	cmp	al,22h
1925
	je	match_quoted_strings
1926
	cmp	al,ah
1927
	je	symbol_characters_matched
1928
	ret
1929
      symbol_characters_matched:
31 halyavin 1930
	lea	ebx,[ebx+1]
157 heavyiron 1931
	lea	esi,[esi+1]
1932
	ret
1933
      match_quoted_strings:
31 halyavin 1934
	mov	ecx,[ebx+1]
157 heavyiron 1935
	add	ecx,5
1936
	jmp	compare_elements
1937
      match_symbols:
31 halyavin 1938
	movzx	ecx,byte [ebx+1]
157 heavyiron 1939
	add	ecx,2
1940
      compare_elements:
31 halyavin 1941
	mov	eax,esi
157 heavyiron 1942
	mov	ebp,edi
1943
	mov	edi,ebx
1944
	repe	cmps byte [esi],[edi]
1945
	jne	elements_mismatch
1946
	mov	ebx,edi
1947
	mov	edi,ebp
1948
	ret
1949
      elements_mismatch:
31 halyavin 1950
	mov	esi,eax
157 heavyiron 1951
	mov	edi,ebp
1952
	ret
1953
      end_matching:
31 halyavin 1954
	cmp	byte [ebx],','
157 heavyiron 1955
	jne	instant_macro_done
1956
      matched_pattern:
31 halyavin 1957
	xor	eax,eax
157 heavyiron 1958
	push	[free_additional_memory]
1959
	push	[macro_symbols]
1960
	mov	[macro_symbols],eax
1961
	push	[counter_limit]
1962
	mov	[counter_limit],eax
1963
	mov	[struc_name],eax
1964
	push	esi edi edx
1965
      add_matched_symbol:
31 halyavin 1966
	cmp	edi,[esp]
157 heavyiron 1967
	je	matched_symbols_ok
1968
	mov	esi,[edi]
1969
	inc	esi
1970
	lods	byte [esi]
1971
	movzx	ecx,al
1972
	xor	eax,eax
1973
	call	add_macro_symbol
1974
	mov	eax,[edi+4]
1975
	mov	dword [edx+12],eax
1976
	mov	ecx,[edi+8]
1977
	sub	ecx,eax
1978
	mov	dword [edx+8],ecx
1979
	add	edi,12
1980
	jmp	add_matched_symbol
1981
      matched_symbols_ok:
31 halyavin 1982
	pop	edx edi esi
157 heavyiron 1983
	jmp	instant_macro_parameters_ok
1984
31 halyavin 1985
 
1986
	push	dword [macro_status]
157 heavyiron 1987
	or	[macro_status],10h
1988
	push	[counter]
1989
	push	[macro_block]
1990
	push	[macro_block_line]
1991
	push	[macro_block_line_number]
1992
	push	[struc_label]
1993
	push	[struc_name]
1994
	push	eax
1995
	push	[current_line]
1996
	lods	byte [esi]
1997
	cmp	al,'{'
1998
	je	macro_instructions_start
1999
	or	al,al
2000
	jnz	unexpected_characters
2001
      find_macro_instructions:
31 halyavin 2002
	mov	[macro_line],esi
157 heavyiron 2003
	add	esi,16+2
2004
	lods	byte [esi]
2005
	or	al,al
2006
	jz	find_macro_instructions
2007
	cmp	al,'{'
2008
	je	macro_instructions_start
2009
	cmp	al,3Bh
2010
	jne	unexpected_characters
2011
	call	skip_foreign_symbol
2012
	jmp	find_macro_instructions
2013
      macro_instructions_start:
31 halyavin 2014
	mov	ecx,80000000h
157 heavyiron 2015
	mov	[macro_block],esi
2016
	mov	eax,[macro_line]
2017
	mov	[macro_block_line],eax
2018
	mov	[macro_block_line_number],ecx
2019
	xor	eax,eax
2020
	mov	[counter],eax
2021
	cmp	[counter_limit],eax
2022
	je	process_macro_line
2023
	inc	[counter]
2024
      process_macro_line:
31 halyavin 2025
	mov	[current_line],edi
157 heavyiron 2026
	lea	eax,[edi+10h]
2027
	cmp	eax,[memory_end]
2028
	jae	out_of_memory
2029
	mov	eax,[esp+4]
2030
	or	eax,eax
2031
	jz	instant_macro_line_header
2032
	stos	dword [edi]
2033
	mov	eax,ecx
2034
	stos	dword [edi]
2035
	mov	eax,[esp]
2036
	stos	dword [edi]
2037
	mov	eax,[macro_line]
2038
	stos	dword [edi]
2039
	jmp	macro_line_header_ok
2040
      instant_macro_line_header:
31 halyavin 2041
	mov	edx,[macro_line]
157 heavyiron 2042
	mov	eax,[edx]
2043
	stos	dword [edi]
2044
	mov	eax,[edx+4]
2045
	stos	dword [edi]
2046
	mov	eax,[edx+8]
2047
	stos	dword [edi]
2048
	mov	eax,[edx+12]
2049
	stos	dword [edi]
2050
      macro_line_header_ok:
31 halyavin 2051
	or	[macro_status],20h
157 heavyiron 2052
	push	ebx ecx
2053
	test	[macro_status],0Fh
2054
	jz	process_macro_line_element
2055
	mov	ax,3Bh
2056
	stos	word [edi]
2057
      process_macro_line_element:
31 halyavin 2058
	lea	eax,[edi+100h]
157 heavyiron 2059
	cmp	eax,[memory_end]
2060
	jae	out_of_memory
2061
	lods	byte [esi]
2062
	cmp	al,'}'
2063
	je	macro_line_processed
2064
	or	al,al
2065
	jz	macro_line_processed
2066
	cmp	al,1Ah
2067
	je	process_macro_symbol
2068
	cmp	al,3Bh
2069
	je	macro_foreign_line
2070
	and	[macro_status],not 20h
2071
	stos	byte [edi]
2072
	cmp	al,22h
2073
	jne	process_macro_line_element
2074
      copy_macro_string:
31 halyavin 2075
	mov	ecx,[esi]
157 heavyiron 2076
	add	ecx,4
2077
	call	move_data
2078
	jmp	process_macro_line_element
2079
      process_macro_symbol:
31 halyavin 2080
	push	esi edi
157 heavyiron 2081
	test	[macro_status],20h
2082
	jz	not_macro_directive
2083
	movzx	ecx,byte [esi]
2084
	inc	esi
2085
	mov	edi,macro_directives
2086
	call	get_directive
2087
	jnc	process_macro_directive
2088
	dec	esi
2089
	jmp	not_macro_directive
2090
      process_macro_directive:
31 halyavin 2091
	mov	edx,eax
157 heavyiron 2092
	pop	edi eax
2093
	mov	byte [edi],0
2094
	inc	edi
2095
	pop	ecx ebx
2096
	jmp	near edx
2097
      not_macro_directive:
31 halyavin 2098
	and	[macro_status],not 20h
157 heavyiron 2099
	movzx	ecx,byte [esi]
2100
	inc	esi
2101
	mov	eax,[counter]
2102
	call	get_macro_symbol
2103
	jnc	group_macro_symbol
2104
	xor	eax,eax
2105
	cmp	[counter],eax
2106
	je	multiple_macro_symbol_values
2107
	call	get_macro_symbol
2108
	jc	not_macro_symbol
2109
      replace_macro_symbol:
31 halyavin 2110
	pop	edi eax
157 heavyiron 2111
	mov	ecx,[edx+8]
2112
	and	ecx,not 80000000h
2113
	mov	edx,[edx+12]
2114
	or	edx,edx
2115
	jz	replace_macro_counter
2116
	xchg	esi,edx
2117
	call	move_data
2118
	mov	esi,edx
2119
	jmp	process_macro_line_element
2120
      group_macro_symbol:
31 halyavin 2121
	xor	eax,eax
157 heavyiron 2122
	cmp	[counter],eax
2123
	je	replace_macro_symbol
2124
	push	esi edx
2125
	sub	esi,ecx
2126
	call	get_macro_symbol
2127
	mov	ebx,edx
2128
	pop	edx esi
2129
	jc	replace_macro_symbol
2130
	cmp	edx,ebx
2131
	ja	replace_macro_symbol
2132
	mov	edx,ebx
2133
	jmp	replace_macro_symbol
2134
      multiple_macro_symbol_values:
31 halyavin 2135
	inc	eax
157 heavyiron 2136
	push	eax
2137
	call	get_macro_symbol
2138
	pop	eax
2139
	jc	not_macro_symbol
2140
	pop	edi
2141
	push	ecx
2142
	mov	ecx,[edx+8]
2143
	mov	edx,[edx+12]
2144
	xchg	esi,edx
2145
	btr	ecx,31
2146
	jc	enclose_macro_symbol_value
2147
	rep	movs byte [edi],[esi]
2148
	jmp	macro_symbol_value_ok
2149
      enclose_macro_symbol_value:
31 halyavin 2150
	mov	byte [edi],'<'
157 heavyiron 2151
	inc	edi
2152
	rep	movs byte [edi],[esi]
2153
	mov	byte [edi],'>'
2154
	inc	edi
2155
      macro_symbol_value_ok:
31 halyavin 2156
	cmp	eax,[counter_limit]
157 heavyiron 2157
	je	multiple_macro_symbol_values_ok
2158
	mov	byte [edi],','
2159
	inc	edi
2160
	mov	esi,edx
2161
	pop	ecx
2162
	push	edi
2163
	sub	esi,ecx
2164
	jmp	multiple_macro_symbol_values
2165
      multiple_macro_symbol_values_ok:
31 halyavin 2166
	pop	ecx eax
157 heavyiron 2167
	mov	esi,edx
2168
	jmp	process_macro_line_element
2169
      replace_macro_counter:
31 halyavin 2170
	mov	eax,[counter]
157 heavyiron 2171
	and	eax,not 80000000h
2172
	jz	group_macro_counter
2173
	add	ecx,eax
2174
	dec	ecx
2175
	call	store_number_symbol
2176
	jmp	process_macro_line_element
2177
      group_macro_counter:
31 halyavin 2178
	mov	edx,ecx
157 heavyiron 2179
	xor	ecx,ecx
2180
      multiple_macro_counter_values:
31 halyavin 2181
	push	ecx edx
157 heavyiron 2182
	add	ecx,edx
2183
	call	store_number_symbol
2184
	pop	edx ecx
2185
	inc	ecx
2186
	cmp	ecx,[counter_limit]
2187
	je	process_macro_line_element
2188
	mov	byte [edi],','
2189
	inc	edi
2190
	jmp	multiple_macro_counter_values
2191
      store_number_symbol:
31 halyavin 2192
	mov	ax,1Ah
157 heavyiron 2193
	stos	word [edi]
2194
	push	edi
2195
	mov	eax,ecx
2196
	mov	ecx,1000000000
2197
	xor	edx,edx
2198
	xor	bl,bl
2199
      store_number_digits:
31 halyavin 2200
	div	ecx
157 heavyiron 2201
	push	edx
2202
	or	bl,bl
2203
	jnz	store_number_digit
2204
	cmp	ecx,1
2205
	je	store_number_digit
2206
	or	al,al
2207
	jz	number_digit_ok
2208
	not	bl
2209
      store_number_digit:
31 halyavin 2210
	add	al,30h
157 heavyiron 2211
	stos	byte [edi]
2212
      number_digit_ok:
31 halyavin 2213
	mov	eax,ecx
157 heavyiron 2214
	xor	edx,edx
2215
	mov	ecx,10
2216
	div	ecx
2217
	mov	ecx,eax
2218
	pop	eax
2219
	or	ecx,ecx
2220
	jnz	store_number_digits
2221
	pop	ebx
2222
	mov	eax,edi
2223
	sub	eax,ebx
2224
	mov	[ebx-1],al
2225
	ret
2226
      not_macro_symbol:
31 halyavin 2227
	pop	edi esi
157 heavyiron 2228
	mov	al,1Ah
2229
	stos	byte [edi]
2230
	mov	al,[esi]
2231
	inc	esi
2232
	stos	byte [edi]
2233
	cmp	byte [esi],'.'
2234
	jne	copy_raw_symbol
2235
	mov	ebx,[esp+8+8]
2236
	or	ebx,ebx
2237
	jz	copy_raw_symbol
2238
	cmp	al,1
2239
	je	copy_struc_name
2240
	xchg	esi,ebx
2241
	movzx	ecx,byte [esi-1]
2242
	add	[edi-1],cl
2243
	jc	name_too_long
2244
	rep	movs byte [edi],[esi]
2245
	xchg	esi,ebx
2246
      copy_raw_symbol:
31 halyavin 2247
	movzx	ecx,al
157 heavyiron 2248
	rep	movs byte [edi],[esi]
2249
	jmp	process_macro_line_element
2250
      copy_struc_name:
31 halyavin 2251
	inc	esi
157 heavyiron 2252
	xchg	esi,ebx
2253
	movzx	ecx,byte [esi-1]
2254
	mov	[edi-1],cl
2255
	rep	movs byte [edi],[esi]
2256
	xchg	esi,ebx
2257
	mov	eax,[esp+8+12]
2258
	cmp	byte [eax],3Bh
2259
	je	process_macro_line_element
2260
	cmp	byte [eax],1Ah
2261
	jne	disable_replaced_struc_name
2262
	mov	byte [eax],3Bh
2263
	jmp	process_macro_line_element
2264
      disable_replaced_struc_name:
31 halyavin 2265
	mov	ebx,[esp+8+8]
157 heavyiron 2266
	push	esi edi
2267
	lea	edi,[ebx-3]
2268
	lea	esi,[edi-2]
2269
	lea	ecx,[esi+1]
2270
	sub	ecx,eax
2271
	std
2272
	rep	movs byte [edi],[esi]
2273
	cld
2274
	mov	word [eax],3Bh
2275
	pop	edi esi
2276
	jmp	process_macro_line_element
2277
      skip_foreign_symbol:
31 halyavin 2278
	lods	byte [esi]
157 heavyiron 2279
	movzx	eax,al
2280
	add	esi,eax
2281
      skip_foreign_line:
31 halyavin 2282
	lods	byte [esi]
157 heavyiron 2283
	cmp	al,1Ah
2284
	je	skip_foreign_symbol
2285
	cmp	al,3Bh
2286
	je	skip_foreign_symbol
2287
	cmp	al,22h
2288
	je	skip_foreign_string
2289
	or	al,al
2290
	jnz	skip_foreign_line
2291
	ret
2292
      skip_foreign_string:
31 halyavin 2293
	lods	dword [esi]
157 heavyiron 2294
	add	esi,eax
2295
	jmp	skip_foreign_line
2296
      macro_foreign_line:
31 halyavin 2297
	call	skip_foreign_symbol
157 heavyiron 2298
      macro_line_processed:
31 halyavin 2299
	mov	byte [edi],0
157 heavyiron 2300
	inc	edi
2301
	push	eax
2302
	call	preprocess_line
2303
	pop	eax
2304
	pop	ecx ebx
2305
	cmp	al,'}'
2306
	je	macro_block_processed
2307
      process_next_line:
31 halyavin 2308
	inc	ecx
157 heavyiron 2309
	mov	[macro_line],esi
2310
	add	esi,16+2
2311
	jmp	process_macro_line
2312
      macro_block_processed:
31 halyavin 2313
	call	close_macro_block
157 heavyiron 2314
	jc	process_macro_line
2315
	pop	[current_line]
2316
	add	esp,12
2317
	pop	[macro_block_line_number]
2318
	pop	[macro_block_line]
2319
	pop	[macro_block]
2320
	pop	[counter]
2321
	pop	eax
2322
	and	al,0F0h
2323
	and	[macro_status],0Fh
2324
	or	[macro_status],al
2325
	ret
2326
31 halyavin 2327
 
2328
	lods	byte [esi]
157 heavyiron 2329
	cmp	al,1Ah
2330
	jne	invalid_argument
2331
	mov	byte [edi-1],3Bh
2332
	xor	al,al
2333
	stos	byte [edi]
2334
      make_local_symbol:
31 halyavin 2335
	push	ecx
157 heavyiron 2336
	lods	byte [esi]
2337
	movzx	ecx,al
2338
	mov	eax,[counter]
2339
	call	add_macro_symbol
2340
	mov	[edx+12],edi
2341
	movzx	eax,[locals_counter]
2342
	add	eax,ecx
2343
	inc	eax
2344
	cmp	eax,100h
2345
	jae	name_too_long
2346
	lea	ebp,[edi+2+eax]
2347
	cmp	ebp,[memory_end]
2348
	jae	out_of_memory
2349
	mov	ah,al
2350
	mov	al,1Ah
2351
	stos	word [edi]
2352
	rep	movs byte [edi],[esi]
2353
	mov	al,'?'
2354
	stos	byte [edi]
2355
	push	esi
2356
	mov	esi,locals_counter+1
2357
	movzx	ecx,[locals_counter]
2358
	rep	movs byte [edi],[esi]
2359
	pop	esi
2360
	mov	eax,edi
2361
	sub	eax,[edx+12]
2362
	mov	[edx+8],eax
2363
	xor	al,al
2364
	stos	byte [edi]
2365
	mov	eax,locals_counter
2366
	movzx	ecx,byte [eax]
2367
      counter_loop:
31 halyavin 2368
	inc	byte [eax+ecx]
157 heavyiron 2369
	cmp	byte [eax+ecx],'9'+1
692 heavyiron 2370
	jb	counter_ok
157 heavyiron 2371
	jne	letter_digit
2372
	mov	byte [eax+ecx],'A'
2373
	jmp	counter_ok
2374
      letter_digit:
31 halyavin 2375
	cmp	byte [eax+ecx],'Z'+1
692 heavyiron 2376
	jb	counter_ok
2377
	jne	small_letter_digit
2378
	mov	byte [eax+ecx],'a'
2379
	jmp	counter_ok
2380
      small_letter_digit:
2381
	cmp	byte [eax+ecx],'z'+1
2382
	jb	counter_ok
2383
	mov	byte [eax+ecx],'0'
157 heavyiron 2384
	loop	counter_loop
2385
	inc	byte [eax]
692 heavyiron 2386
	movzx	ecx,byte [eax]
2387
	mov	byte [eax+ecx],'0'
2388
      counter_ok:
31 halyavin 2389
	pop	ecx
157 heavyiron 2390
	lods	byte [esi]
2391
	cmp	al,'}'
2392
	je	macro_block_processed
2393
	or	al,al
2394
	jz	process_next_line
2395
	cmp	al,','
2396
	jne	extra_characters_on_line
2397
	dec	edi
2398
	lods	byte [esi]
2399
	cmp	al,1Ah
2400
	je	make_local_symbol
2401
	jmp	invalid_argument
2402
common_block:
31 halyavin 2403
	call	close_macro_block
157 heavyiron 2404
	jc	process_macro_line
2405
	mov	[counter],0
2406
	jmp	new_macro_block
2407
forward_block:
31 halyavin 2408
	cmp	[counter_limit],0
157 heavyiron 2409
	je	common_block
2410
	call	close_macro_block
2411
	jc	process_macro_line
2412
	mov	[counter],1
2413
	jmp	new_macro_block
2414
reverse_block:
31 halyavin 2415
	cmp	[counter_limit],0
157 heavyiron 2416
	je	common_block
2417
	call	close_macro_block
2418
	jc	process_macro_line
2419
	mov	eax,[counter_limit]
2420
	or	eax,80000000h
2421
	mov	[counter],eax
2422
      new_macro_block:
31 halyavin 2423
	mov	[macro_block],esi
157 heavyiron 2424
	mov	eax,[macro_line]
2425
	mov	[macro_block_line],eax
2426
	mov	[macro_block_line_number],ecx
2427
	jmp	process_macro_line
2428
close_macro_block:
31 halyavin 2429
	cmp	[counter],0
157 heavyiron 2430
	je	block_closed
2431
	jl	reverse_counter
2432
	mov	eax,[counter]
2433
	cmp	eax,[counter_limit]
2434
	je	block_closed
2435
	inc	[counter]
2436
	jmp	continue_block
2437
      reverse_counter:
31 halyavin 2438
	mov	eax,[counter]
157 heavyiron 2439
	dec	eax
2440
	cmp	eax,80000000h
2441
	je	block_closed
2442
	mov	[counter],eax
2443
      continue_block:
31 halyavin 2444
	mov	esi,[macro_block]
157 heavyiron 2445
	mov	eax,[macro_block_line]
2446
	mov	[macro_line],eax
2447
	mov	ecx,[macro_block_line_number]
2448
	stc
2449
	ret
2450
      block_closed:
31 halyavin 2451
	clc
157 heavyiron 2452
	ret
2453
get_macro_symbol:
31 halyavin 2454
	push	ecx
157 heavyiron 2455
	call	find_macro_symbol_leaf
2456
	jc	macro_symbol_not_found
2457
	mov	edx,[ebx]
2458
	mov	ebx,esi
2459
      try_macro_symbol:
31 halyavin 2460
	or	edx,edx
157 heavyiron 2461
	jz	macro_symbol_not_found
2462
	mov	ecx,[esp]
2463
	mov	edi,[edx+4]
2464
	repe	cmps byte [esi],[edi]
2465
	je	macro_symbol_found
2466
	mov	esi,ebx
2467
	mov	edx,[edx]
2468
	jmp	try_macro_symbol
2469
      macro_symbol_found:
31 halyavin 2470
	pop	ecx
157 heavyiron 2471
	clc
2472
	ret
2473
      macro_symbol_not_found:
31 halyavin 2474
	pop	ecx
157 heavyiron 2475
	stc
2476
	ret
2477
      find_macro_symbol_leaf:
31 halyavin 2478
	shl	eax,8
157 heavyiron 2479
	mov	al,cl
2480
	mov	ebp,eax
2481
	mov	ebx,macro_symbols
2482
      follow_macro_symbols_tree:
31 halyavin 2483
	mov	edx,[ebx]
157 heavyiron 2484
	or	edx,edx
2485
	jz	no_such_macro_symbol
2486
	xor	eax,eax
2487
	shr	ebp,1
2488
	adc	eax,0
2489
	lea	ebx,[edx+eax*4]
2490
	or	ebp,ebp
2491
	jnz	follow_macro_symbols_tree
2492
	add	ebx,8
2493
	clc
2494
	ret
2495
      no_such_macro_symbol:
31 halyavin 2496
	stc
157 heavyiron 2497
	ret
2498
add_macro_symbol:
31 halyavin 2499
	push	ebx ebp
157 heavyiron 2500
	call	find_macro_symbol_leaf
2501
	jc	extend_macro_symbol_tree
2502
	mov	eax,[ebx]
2503
      make_macro_symbol:
31 halyavin 2504
	mov	edx,[free_additional_memory]
157 heavyiron 2505
	add	edx,16
2506
	cmp	edx,[labels_list]
2507
	ja	out_of_memory
2508
	xchg	edx,[free_additional_memory]
2509
	mov	[ebx],edx
2510
	mov	[edx],eax
2511
	mov	[edx+4],esi
2512
	pop	ebp ebx
2513
	ret
2514
      extend_macro_symbol_tree:
31 halyavin 2515
	mov	edx,[free_additional_memory]
157 heavyiron 2516
	add	edx,16
2517
	cmp	edx,[labels_list]
2518
	ja	out_of_memory
2519
	xchg	edx,[free_additional_memory]
2520
	xor	eax,eax
2521
	mov	[edx],eax
2522
	mov	[edx+4],eax
2523
	mov	[edx+8],eax
2524
	mov	[edx+12],eax
2525
	shr	ebp,1
2526
	adc	eax,0
2527
	mov	[ebx],edx
2528
	lea	ebx,[edx+eax*4]
2529
	or	ebp,ebp
2530
	jnz	extend_macro_symbol_tree
2531
	add	ebx,8
2532
	xor	eax,eax
2533
	jmp	make_macro_symbol
2534
31 halyavin 2535
 
2536
	lods	byte [esi]
157 heavyiron 2537
	cmp	al,22h
2538
	jne	invalid_argument
2539
	lods	dword [esi]
2540
	cmp	byte [esi+eax],0
2541
	jne	extra_characters_on_line
2542
	push	esi
2543
	push	edi
2544
	mov	ebx,[current_line]
2545
      find_current_file_path:
31 halyavin 2546
	mov	esi,[ebx]
157 heavyiron 2547
	test	byte [ebx+7],80h
2548
	jz	copy_current_file_path
2549
	mov	ebx,[ebx+8]
2550
	jmp	find_current_file_path
2551
      copy_current_file_path:
31 halyavin 2552
	lods	byte [esi]
157 heavyiron 2553
	stos	byte [edi]
2554
	or	al,al
2555
	jnz	copy_current_file_path
2556
      cut_current_file_name:
31 halyavin 2557
	cmp	edi,[esp]
157 heavyiron 2558
	je	current_file_path_ok
2559
	cmp	byte [edi-1],'\'
2560
	je	current_file_path_ok
2561
	cmp	byte [edi-1],'/'
2562
	je	current_file_path_ok
2563
	dec	edi
2564
	jmp	cut_current_file_name
2565
      current_file_path_ok:
31 halyavin 2566
	mov	esi,[esp+4]
157 heavyiron 2567
	call	preprocess_path
2568
	pop	edx
2569
	mov	esi,edx
2570
	call	open
2571
	jnc	include_path_ok
2572
	mov	ebp,[include_paths]
2573
      try_include_directories:
31 halyavin 2574
	mov	edi,esi
157 heavyiron 2575
	mov	esi,ebp
2576
	cmp	byte [esi],0
2577
	je	try_in_current_directory
2578
	push	ebp
2579
	push	edi
2580
      copy_include_directory:
31 halyavin 2581
	lods	byte [esi]
157 heavyiron 2582
	cmp	al,';'
2583
	je	include_directory_ok
2584
	stos	byte [edi]
2585
	or	al,al
2586
	jnz	copy_include_directory
2587
	dec	esi
2588
	dec	edi
2589
      include_directory_ok:
31 halyavin 2590
	cmp	byte [edi-1],'/'
157 heavyiron 2591
	je	path_separator_ok
2592
	cmp	byte [edi-1],'\'
2593
	je	path_separator_ok
2594
	mov	al,'/'
2595
	stos	byte [edi]
2596
      path_separator_ok:
31 halyavin 2597
	mov	[esp+4],esi
157 heavyiron 2598
	mov	esi,[esp+8]
2599
	call	preprocess_path
2600
	pop	edx
2601
	mov	esi,edx
2602
	call	open
2603
	pop	ebp
2604
	jnc	include_path_ok
2605
	jmp	try_include_directories
2606
	mov	edi,esi
2607
      try_in_current_directory:
31 halyavin 2608
	mov	esi,[esp]
157 heavyiron 2609
	push	edi
2610
	call	preprocess_path
2611
	pop	edx
2612
	mov	esi,edx
2613
	call	open
2614
	jc	file_not_found
2615
      include_path_ok:
31 halyavin 2616
	mov	edi,[esp]
157 heavyiron 2617
      copy_preprocessed_path:
31 halyavin 2618
	lods	byte [esi]
157 heavyiron 2619
	stos	byte [edi]
2620
	or	al,al
2621
	jnz	copy_preprocessed_path
2622
	pop	esi
2623
	lea	ecx,[edi-1]
2624
	sub	ecx,esi
2625
	mov	[esi-4],ecx
2626
	push	dword [macro_status]
2627
	and	[macro_status],0Fh
2628
	call	preprocess_file
2629
	pop	eax
2630
	mov	[macro_status],al
2631
	jmp	line_preprocessed
2632
      preprocess_path:
31 halyavin 2633
	lods	byte [esi]
157 heavyiron 2634
	cmp	al,'%'
2635
	je	environment_variable
2636
	stos	byte [edi]
2637
	or	al,al
2638
	jnz	preprocess_path
2639
	cmp	edi,[memory_end]
2640
	ja	out_of_memory
2641
	ret
2642
      environment_variable:
31 halyavin 2643
	mov	ebx,esi
157 heavyiron 2644
      find_variable_end:
31 halyavin 2645
	lods	byte [esi]
157 heavyiron 2646
	or	al,al
2647
	jz	not_environment_variable
2648
	cmp	al,'%'
2649
	jne	find_variable_end
2650
	mov	byte [esi-1],0
2651
	push	esi
2652
	mov	esi,ebx
2653
	call	get_environment_variable
2654
	pop	esi
2655
	mov	byte [esi-1],'%'
2656
	jmp	preprocess_path
2657
      not_environment_variable:
31 halyavin 2658
	mov	al,'%'
157 heavyiron 2659
	stos	byte [edi]
2660
	mov	esi,ebx
2661
	jmp	preprocess_path
2662
>