"Fossies" - the Fresh Open Source Software Archive

Member "fasm/source/preproce.inc" (21 Feb 2022, 55676 Bytes) of package /linux/misc/fasm-1.73.30.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) fasm source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "preproce.inc": 1.73.29_vs_1.73.30.

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