"Fossies" - the Fresh Open Source Software Archive

Member "fasm/source/preproce.inc" (9 Feb 2020, 54020 Bytes) of package /linux/misc/fasm-1.73.22.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.21_vs_1.73.22.

    1 
    2 ; flat assembler core
    3 ; Copyright (c) 1999-2020, 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  unexpected_end_of_file
  406     or  al,al
  407     jz  unexpected_end_of_file
  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  unexpected_end_of_file
  434     or  al,al
  435     jz  unexpected_end_of_file
  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  unexpected_end_of_file
  478     or  al,al
  479     jz  unexpected_end_of_file
  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 unexpected_end_of_file
  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     mov ecx,[edx+12]
  690     add ecx,3
  691     lea ebx,[edi+ecx]
  692     mov ecx,edi
  693     sub ecx,[struc_label]
  694     lea esi,[edi-1]
  695     lea edi,[ebx-1]
  696     std
  697     rep movs byte [edi],[esi]
  698     cld
  699     mov edi,[struc_label]
  700     mov esi,[edx+8]
  701     mov ecx,[edx+12]
  702     add [struc_name],ecx
  703     add [struc_name],3
  704     call    move_data
  705     mov al,3Ah
  706     stos    byte [edi]
  707     mov ax,3Bh
  708     stos    word [edi]
  709     mov edi,ebx
  710     pop esi
  711     add esi,[edx+12]
  712     add esi,3
  713     pop edx
  714     jmp use_macro
  715       struc_name_ok:
  716     mov edx,[struc_name]
  717     movzx   eax,byte [edx-1]
  718     add edx,eax
  719     push    edi
  720     lea esi,[edi-1]
  721     mov ecx,edi
  722     sub ecx,edx
  723     std
  724     rep movs byte [edi],[esi]
  725     cld
  726     pop edi
  727     inc edi
  728     mov al,3Ah
  729     mov [edx],al
  730     inc al
  731     mov [edx+1],al
  732     pop esi edx
  733     inc esi
  734     jmp use_macro
  735       preprocess_label:
  736     dec esi
  737     sub esi,ecx
  738     lea ebp,[esi-2]
  739     mov ch,10b
  740     call    get_preprocessor_symbol
  741     jnc symbolic_constant_in_label
  742     lea esi,[esi+ecx+1]
  743     cmp byte [esi],':'
  744     jne preprocess_instruction
  745     inc esi
  746     jmp preprocess_instruction
  747       symbolic_constant_in_label:
  748     mov ebx,[edx+8]
  749     mov ecx,[edx+12]
  750     add ecx,ebx
  751       check_for_broken_label:
  752     cmp ebx,ecx
  753     je  label_broken
  754     cmp byte [ebx],1Ah
  755     jne label_broken
  756     movzx   eax,byte [ebx+1]
  757     lea ebx,[ebx+2+eax]
  758     cmp ebx,ecx
  759     je  label_constant_ok
  760     cmp byte [ebx],':'
  761     jne label_broken
  762     inc ebx
  763     cmp byte [ebx],':'
  764     jne check_for_broken_label
  765     inc ebx
  766     jmp check_for_broken_label
  767       label_broken:
  768     call    replace_symbolic_constant
  769     jmp line_preprocessed
  770       label_constant_ok:
  771     mov ecx,edi
  772     sub ecx,esi
  773     mov edi,[edx+12]
  774     add edi,ebp
  775     push    edi
  776     lea eax,[edi+ecx]
  777     push    eax
  778     cmp esi,edi
  779     je  replace_label
  780     jb  move_rest_of_line_up
  781     rep movs byte [edi],[esi]
  782     jmp replace_label
  783       move_rest_of_line_up:
  784     lea esi,[esi+ecx-1]
  785     lea edi,[edi+ecx-1]
  786     std
  787     rep movs byte [edi],[esi]
  788     cld
  789       replace_label:
  790     mov ecx,[edx+12]
  791     mov edi,[esp+4]
  792     sub edi,ecx
  793     mov esi,[edx+8]
  794     rep movs byte [edi],[esi]
  795     pop edi esi
  796     inc esi
  797     jmp preprocess_instruction
  798       not_preprocessor_symbol:
  799     mov esi,[current_offset]
  800     call    process_equ_constants
  801       line_preprocessed:
  802     pop esi ecx
  803     ret
  804 
  805 get_preprocessor_symbol:
  806     push    ebp edi esi
  807     mov ebp,ecx
  808     shl ebp,22
  809     movzx   ecx,cl
  810     mov ebx,hash_tree
  811     mov edi,10
  812       follow_hashes_roots:
  813     mov edx,[ebx]
  814     or  edx,edx
  815     jz  preprocessor_symbol_not_found
  816     xor eax,eax
  817     shl ebp,1
  818     adc eax,0
  819     lea ebx,[edx+eax*4]
  820     dec edi
  821     jnz follow_hashes_roots
  822     mov edi,ebx
  823     call    calculate_hash
  824     mov ebp,eax
  825     and ebp,3FFh
  826     shl ebp,10
  827     xor ebp,eax
  828     mov ebx,edi
  829     mov edi,22
  830       follow_hashes_tree:
  831     mov edx,[ebx]
  832     or  edx,edx
  833     jz  preprocessor_symbol_not_found
  834     xor eax,eax
  835     shl ebp,1
  836     adc eax,0
  837     lea ebx,[edx+eax*4]
  838     dec edi
  839     jnz follow_hashes_tree
  840     mov al,cl
  841     mov edx,[ebx]
  842     or  edx,edx
  843     jz  preprocessor_symbol_not_found
  844       compare_with_preprocessor_symbol:
  845     mov edi,[edx+4]
  846     cmp edi,1
  847     jbe next_equal_hash
  848     repe    cmps byte [esi],[edi]
  849     je  preprocessor_symbol_found
  850     mov cl,al
  851     mov esi,[esp]
  852       next_equal_hash:
  853     mov edx,[edx]
  854     or  edx,edx
  855     jnz compare_with_preprocessor_symbol
  856       preprocessor_symbol_not_found:
  857     pop esi edi ebp
  858     stc
  859     ret
  860       preprocessor_symbol_found:
  861     pop ebx edi ebp
  862     clc
  863     ret
  864       calculate_hash:
  865     xor ebx,ebx
  866     mov eax,2166136261
  867     mov ebp,16777619
  868       fnv1a_hash:
  869     xor al,[esi+ebx]
  870     mul ebp
  871     inc bl
  872     cmp bl,cl
  873     jb  fnv1a_hash
  874     ret
  875 add_preprocessor_symbol:
  876     push    edi esi
  877     xor eax,eax
  878     or  cl,cl
  879     jz  reshape_hash
  880     cmp ch,11b
  881     je  preprocessor_symbol_name_ok
  882     push    ecx
  883     movzx   ecx,cl
  884     mov edi,preprocessor_directives
  885     call    get_directive
  886     jnc reserved_word_used_as_symbol
  887     pop ecx
  888       preprocessor_symbol_name_ok:
  889     call    calculate_hash
  890       reshape_hash:
  891     mov ebp,eax
  892     and ebp,3FFh
  893     shr eax,10
  894     xor ebp,eax
  895     shl ecx,22
  896     or  ebp,ecx
  897     mov ebx,hash_tree
  898     mov ecx,32
  899       find_leave_for_symbol:
  900     mov edx,[ebx]
  901     or  edx,edx
  902     jz  extend_hashes_tree
  903     xor eax,eax
  904     rol ebp,1
  905     adc eax,0
  906     lea ebx,[edx+eax*4]
  907     dec ecx
  908     jnz find_leave_for_symbol
  909     mov edx,[ebx]
  910     or  edx,edx
  911     jz  add_symbol_entry
  912     shr ebp,30
  913     cmp ebp,11b
  914     je  reuse_symbol_entry
  915     cmp dword [edx+4],0
  916     jne add_symbol_entry
  917       find_entry_to_reuse:
  918     mov edi,[edx]
  919     or  edi,edi
  920     jz  reuse_symbol_entry
  921     cmp dword [edi+4],0
  922     jne reuse_symbol_entry
  923     mov edx,edi
  924     jmp find_entry_to_reuse
  925       add_symbol_entry:
  926     mov eax,edx
  927     mov edx,[labels_list]
  928     sub edx,16
  929     cmp edx,[free_additional_memory]
  930     jb  out_of_memory
  931     mov [labels_list],edx
  932     mov [edx],eax
  933     mov [ebx],edx
  934       reuse_symbol_entry:
  935     pop esi edi
  936     mov [edx+4],esi
  937     ret
  938       extend_hashes_tree:
  939     mov edx,[labels_list]
  940     sub edx,8
  941     cmp edx,[free_additional_memory]
  942     jb  out_of_memory
  943     mov [labels_list],edx
  944     xor eax,eax
  945     mov [edx],eax
  946     mov [edx+4],eax
  947     shl ebp,1
  948     adc eax,0
  949     mov [ebx],edx
  950     lea ebx,[edx+eax*4]
  951     dec ecx
  952     jnz extend_hashes_tree
  953     mov edx,[labels_list]
  954     sub edx,16
  955     cmp edx,[free_additional_memory]
  956     jb  out_of_memory
  957     mov [labels_list],edx
  958     mov dword [edx],0
  959     mov [ebx],edx
  960     pop esi edi
  961     mov [edx+4],esi
  962     ret
  963 
  964 define_fix_constant:
  965     add edx,5
  966     add esi,2
  967     push    edx
  968     mov ch,11b
  969     jmp define_preprocessor_constant
  970 define_equ_constant:
  971     add esi,3
  972     push    esi
  973     call    process_equ_constants
  974     mov esi,[struc_name]
  975     mov ch,10b
  976       define_preprocessor_constant:
  977     mov byte [esi-2],3Bh
  978     mov cl,[esi-1]
  979     call    add_preprocessor_symbol
  980     pop ebx
  981     mov ecx,edi
  982     dec ecx
  983     sub ecx,ebx
  984     mov [edx+8],ebx
  985     mov [edx+12],ecx
  986     jmp line_preprocessed
  987 define_symbolic_constant:
  988     lods    byte [esi]
  989     cmp al,1Ah
  990     jne invalid_name
  991     lods    byte [esi]
  992     mov cl,al
  993     mov ch,10b
  994     call    add_preprocessor_symbol
  995     movzx   eax,byte [esi-1]
  996     add esi,eax
  997     lea ecx,[edi-1]
  998     sub ecx,esi
  999     mov [edx+8],esi
 1000     mov [edx+12],ecx
 1001     jmp line_preprocessed
 1002 
 1003 define_struc:
 1004     mov ch,1
 1005     jmp make_macro
 1006 define_macro:
 1007     xor ch,ch
 1008       make_macro:
 1009     lods    byte [esi]
 1010     cmp al,1Ah
 1011     jne invalid_name
 1012     lods    byte [esi]
 1013     mov cl,al
 1014     call    add_preprocessor_symbol
 1015     mov eax,[current_line]
 1016     mov [edx+12],eax
 1017     movzx   eax,byte [esi-1]
 1018     add esi,eax
 1019     mov [edx+8],esi
 1020     mov al,[macro_status]
 1021     and al,0F0h
 1022     or  al,1
 1023     mov [macro_status],al
 1024     mov eax,[current_line]
 1025     mov [error_line],eax
 1026     xor ebp,ebp
 1027     lods    byte [esi]
 1028     or  al,al
 1029     jz  line_preprocessed
 1030     cmp al,'{'
 1031     je  found_macro_block
 1032     dec esi
 1033       skip_macro_arguments:
 1034     lods    byte [esi]
 1035     cmp al,1Ah
 1036     je  skip_macro_argument
 1037     cmp al,'['
 1038     jne invalid_macro_arguments
 1039     or  ebp,-1
 1040     jz  invalid_macro_arguments
 1041     lods    byte [esi]
 1042     cmp al,1Ah
 1043     jne invalid_macro_arguments
 1044       skip_macro_argument:
 1045     movzx   eax,byte [esi]
 1046     inc esi
 1047     add esi,eax
 1048     lods    byte [esi]
 1049     cmp al,':'
 1050     je  macro_argument_with_default_value
 1051     cmp al,'='
 1052     je  macro_argument_with_default_value
 1053     cmp al,'*'
 1054     jne macro_argument_end
 1055     lods    byte [esi]
 1056       macro_argument_end:
 1057     cmp al,','
 1058     je  skip_macro_arguments
 1059     cmp al,'&'
 1060     je  macro_arguments_finisher
 1061     cmp al,']'
 1062     jne end_macro_arguments
 1063     not ebp
 1064       macro_arguments_finisher:
 1065     lods    byte [esi]
 1066       end_macro_arguments:
 1067     or  ebp,ebp
 1068     jnz invalid_macro_arguments
 1069     or  al,al
 1070     jz  line_preprocessed
 1071     cmp al,'{'
 1072     je  found_macro_block
 1073     jmp invalid_macro_arguments
 1074       macro_argument_with_default_value:
 1075     or  [skip_default_argument_value],-1
 1076     call    skip_macro_argument_value
 1077     inc esi
 1078     jmp macro_argument_end
 1079       skip_macro_argument_value:
 1080     cmp byte [esi],'<'
 1081     jne simple_argument
 1082     mov ecx,1
 1083     inc esi
 1084       enclosed_argument:
 1085     lods    byte [esi]
 1086     or  al,al
 1087     jz  invalid_macro_arguments
 1088     cmp al,1Ah
 1089     je  enclosed_symbol
 1090     cmp al,22h
 1091     je  enclosed_string
 1092     cmp al,'>'
 1093     je  enclosed_argument_end
 1094     cmp al,'<'
 1095     jne enclosed_argument
 1096     inc ecx
 1097     jmp enclosed_argument
 1098       enclosed_symbol:
 1099     movzx   eax,byte [esi]
 1100     inc esi
 1101     add esi,eax
 1102     jmp enclosed_argument
 1103       enclosed_string:
 1104     lods    dword [esi]
 1105     add esi,eax
 1106     jmp enclosed_argument
 1107       enclosed_argument_end:
 1108     loop    enclosed_argument
 1109     lods    byte [esi]
 1110     or  al,al
 1111     jz  argument_value_end
 1112     cmp al,','
 1113     je  argument_value_end
 1114     cmp [skip_default_argument_value],0
 1115     je  invalid_macro_arguments
 1116     cmp al,'{'
 1117     je  argument_value_end
 1118     cmp al,'&'
 1119     je  argument_value_end
 1120     or  ebp,ebp
 1121     jz  invalid_macro_arguments
 1122     cmp al,']'
 1123     je  argument_value_end
 1124     jmp invalid_macro_arguments
 1125       simple_argument:
 1126     lods    byte [esi]
 1127     or  al,al
 1128     jz  argument_value_end
 1129     cmp al,','
 1130     je  argument_value_end
 1131     cmp al,22h
 1132     je  argument_string
 1133     cmp al,1Ah
 1134     je  argument_symbol
 1135     cmp [skip_default_argument_value],0
 1136     je  simple_argument
 1137     cmp al,'{'
 1138     je  argument_value_end
 1139     cmp al,'&'
 1140     je  argument_value_end
 1141     or  ebp,ebp
 1142     jz  simple_argument
 1143     cmp al,']'
 1144     je  argument_value_end
 1145       argument_symbol:
 1146     movzx   eax,byte [esi]
 1147     inc esi
 1148     add esi,eax
 1149     jmp simple_argument
 1150       argument_string:
 1151     lods    dword [esi]
 1152     add esi,eax
 1153     jmp simple_argument
 1154       argument_value_end:
 1155     dec esi
 1156     ret
 1157       find_macro_block:
 1158     add esi,2
 1159     lods    byte [esi]
 1160     or  al,al
 1161     jz  line_preprocessed
 1162     cmp al,'{'
 1163     jne unexpected_characters
 1164       found_macro_block:
 1165     or  [macro_status],2
 1166       skip_macro_block:
 1167     lods    byte [esi]
 1168     cmp al,1Ah
 1169     je  skip_macro_symbol
 1170     cmp al,3Bh
 1171     je  skip_macro_symbol
 1172     cmp al,22h
 1173     je  skip_macro_string
 1174     or  al,al
 1175     jz  line_preprocessed
 1176     cmp al,'}'
 1177     jne skip_macro_block
 1178     mov al,[macro_status]
 1179     and [macro_status],0F0h
 1180     test    al,8
 1181     jnz use_instant_macro
 1182     cmp byte [esi],0
 1183     je  line_preprocessed
 1184     mov ecx,edi
 1185     sub ecx,esi
 1186     mov edx,esi
 1187     lea esi,[esi+ecx-1]
 1188     lea edi,[edi+1+16]
 1189     mov ebx,edi
 1190     dec edi
 1191     std
 1192     rep movs byte [edi],[esi]
 1193     cld
 1194     mov edi,edx
 1195     xor al,al
 1196     stos    byte [edi]
 1197     mov esi,[current_line]
 1198     mov [current_line],edi
 1199     mov ecx,4
 1200     rep movs dword [edi],[esi]
 1201     mov edi,ebx
 1202     jmp initial_preprocessing_ok
 1203       skip_macro_symbol:
 1204     movzx   eax,byte [esi]
 1205     inc esi
 1206     add esi,eax
 1207     jmp skip_macro_block
 1208       skip_macro_string:
 1209     lods    dword [esi]
 1210     add esi,eax
 1211     jmp skip_macro_block
 1212 postpone_directive:
 1213     push    esi
 1214     mov esi,edx
 1215     xor ecx,ecx
 1216     call    add_preprocessor_symbol
 1217     mov eax,[current_line]
 1218     mov [error_line],eax
 1219     mov [edx+12],eax
 1220     pop esi
 1221     mov [edx+8],esi
 1222     mov al,[macro_status]
 1223     and al,0F0h
 1224     or  al,1
 1225     mov [macro_status],al
 1226     lods    byte [esi]
 1227     or  al,al
 1228     jz  line_preprocessed
 1229     cmp al,'{'
 1230     jne unexpected_characters
 1231     jmp found_macro_block
 1232 rept_directive:
 1233     mov [base_code],0
 1234     jmp define_instant_macro
 1235 irp_directive:
 1236     mov [base_code],1
 1237     jmp define_instant_macro
 1238 irps_directive:
 1239     mov [base_code],2
 1240     jmp define_instant_macro
 1241 irpv_directive:
 1242     mov [base_code],3
 1243     jmp define_instant_macro
 1244 match_directive:
 1245     mov [base_code],10h
 1246 define_instant_macro:
 1247     mov al,[macro_status]
 1248     and al,0F0h
 1249     or  al,8+1
 1250     mov [macro_status],al
 1251     mov eax,[current_line]
 1252     mov [error_line],eax
 1253     mov [instant_macro_start],esi
 1254     cmp [base_code],10h
 1255     je  prepare_match
 1256       skip_parameters:
 1257     lods    byte [esi]
 1258     or  al,al
 1259     jz  parameters_skipped
 1260     cmp al,'{'
 1261     je  parameters_skipped
 1262     cmp al,22h
 1263     je  skip_quoted_parameter
 1264     cmp al,1Ah
 1265     jne skip_parameters
 1266     lods    byte [esi]
 1267     movzx   eax,al
 1268     add esi,eax
 1269     jmp skip_parameters
 1270       skip_quoted_parameter:
 1271     lods    dword [esi]
 1272     add esi,eax
 1273     jmp skip_parameters
 1274       parameters_skipped:
 1275     dec esi
 1276     mov [parameters_end],esi
 1277     lods    byte [esi]
 1278     cmp al,'{'
 1279     je  found_macro_block
 1280     or  al,al
 1281     jnz invalid_macro_arguments
 1282     jmp line_preprocessed
 1283 prepare_match:
 1284     call    skip_pattern
 1285     mov [value_type],80h+10b
 1286     call    process_symbolic_constants
 1287     jmp parameters_skipped
 1288       skip_pattern:
 1289     lods    byte [esi]
 1290     or  al,al
 1291     jz  invalid_macro_arguments
 1292     cmp al,','
 1293     je  pattern_skipped
 1294     cmp al,22h
 1295     je  skip_quoted_string_in_pattern
 1296     cmp al,1Ah
 1297     je  skip_symbol_in_pattern
 1298     cmp al,'='
 1299     jne skip_pattern
 1300     mov al,[esi]
 1301     cmp al,1Ah
 1302     je  skip_pattern
 1303     cmp al,22h
 1304     je  skip_pattern
 1305     inc esi
 1306     jmp skip_pattern
 1307       skip_symbol_in_pattern:
 1308     lods    byte [esi]
 1309     movzx   eax,al
 1310     add esi,eax
 1311     jmp skip_pattern
 1312       skip_quoted_string_in_pattern:
 1313     lods    dword [esi]
 1314     add esi,eax
 1315     jmp skip_pattern
 1316       pattern_skipped:
 1317     ret
 1318 
 1319 purge_macro:
 1320     xor ch,ch
 1321     jmp restore_preprocessor_symbol
 1322 purge_struc:
 1323     mov ch,1
 1324     jmp restore_preprocessor_symbol
 1325 restore_equ_constant:
 1326     mov ch,10b
 1327       restore_preprocessor_symbol:
 1328     push    ecx
 1329     lods    byte [esi]
 1330     cmp al,1Ah
 1331     jne invalid_name
 1332     lods    byte [esi]
 1333     mov cl,al
 1334     call    get_preprocessor_symbol
 1335     jc  no_symbol_to_restore
 1336     mov dword [edx+4],0
 1337     jmp symbol_restored
 1338       no_symbol_to_restore:
 1339     add esi,ecx
 1340       symbol_restored:
 1341     pop ecx
 1342     lods    byte [esi]
 1343     cmp al,','
 1344     je  restore_preprocessor_symbol
 1345     or  al,al
 1346     jnz extra_characters_on_line
 1347     jmp line_preprocessed
 1348 
 1349 process_fix_constants:
 1350     mov [value_type],11b
 1351     jmp process_symbolic_constants
 1352 process_equ_constants:
 1353     mov [value_type],10b
 1354       process_symbolic_constants:
 1355     mov ebp,esi
 1356     lods    byte [esi]
 1357     cmp al,1Ah
 1358     je  check_symbol
 1359     cmp al,22h
 1360     je  ignore_string
 1361     cmp al,'{'
 1362     je  check_brace
 1363     or  al,al
 1364     jnz process_symbolic_constants
 1365     ret
 1366       ignore_string:
 1367     lods    dword [esi]
 1368     add esi,eax
 1369     jmp process_symbolic_constants
 1370       check_brace:
 1371     test    [value_type],80h
 1372     jz  process_symbolic_constants
 1373     ret
 1374       no_replacing:
 1375     movzx   ecx,byte [esi-1]
 1376     add esi,ecx
 1377     jmp process_symbolic_constants
 1378       check_symbol:
 1379     mov cl,[esi]
 1380     inc esi
 1381     mov ch,[value_type]
 1382     call    get_preprocessor_symbol
 1383     jc  no_replacing
 1384     mov [current_section],edi
 1385       replace_symbolic_constant:
 1386     mov ecx,[edx+12]
 1387     mov edx,[edx+8]
 1388     xchg    esi,edx
 1389     call    move_data
 1390     mov esi,edx
 1391       process_after_replaced:
 1392     lods    byte [esi]
 1393     cmp al,1Ah
 1394     je  symbol_after_replaced
 1395     stos    byte [edi]
 1396     cmp al,22h
 1397     je  string_after_replaced
 1398     cmp al,'{'
 1399     je  brace_after_replaced
 1400     or  al,al
 1401     jnz process_after_replaced
 1402     mov ecx,edi
 1403     sub ecx,esi
 1404     mov edi,ebp
 1405     call    move_data
 1406     mov esi,edi
 1407     ret
 1408       move_data:
 1409     lea eax,[edi+ecx]
 1410     cmp eax,[memory_end]
 1411     jae out_of_memory
 1412     shr ecx,1
 1413     jnc movsb_ok
 1414     movs    byte [edi],[esi]
 1415       movsb_ok:
 1416     shr ecx,1
 1417     jnc movsw_ok
 1418     movs    word [edi],[esi]
 1419       movsw_ok:
 1420     rep movs dword [edi],[esi]
 1421     ret
 1422       string_after_replaced:
 1423     lods    dword [esi]
 1424     stos    dword [edi]
 1425     mov ecx,eax
 1426     call    move_data
 1427     jmp process_after_replaced
 1428       brace_after_replaced:
 1429     test    [value_type],80h
 1430     jz  process_after_replaced
 1431     mov edx,edi
 1432     mov ecx,[current_section]
 1433     sub edx,ecx
 1434     sub ecx,esi
 1435     rep movs byte [edi],[esi]
 1436     mov ecx,edi
 1437     sub ecx,esi
 1438     mov edi,ebp
 1439     call    move_data
 1440     lea esi,[ebp+edx]
 1441     ret
 1442       symbol_after_replaced:
 1443     mov cl,[esi]
 1444     inc esi
 1445     mov ch,[value_type]
 1446     call    get_preprocessor_symbol
 1447     jnc replace_symbolic_constant
 1448     movzx   ecx,byte [esi-1]
 1449     mov al,1Ah
 1450     mov ah,cl
 1451     stos    word [edi]
 1452     call    move_data
 1453     jmp process_after_replaced
 1454 process_macro_operators:
 1455     xor dl,dl
 1456     mov ebp,edi
 1457       before_macro_operators:
 1458     mov edi,esi
 1459     lods    byte [esi]
 1460     cmp al,'`'
 1461     je  symbol_conversion
 1462     cmp al,'#'
 1463     je  concatenation
 1464     cmp al,1Ah
 1465     je  symbol_before_macro_operators
 1466     cmp al,3Bh
 1467     je  no_more_macro_operators
 1468     cmp al,22h
 1469     je  string_before_macro_operators
 1470     xor dl,dl
 1471     or  al,al
 1472     jnz before_macro_operators
 1473     mov edi,esi
 1474     ret
 1475       no_more_macro_operators:
 1476     mov edi,ebp
 1477     ret
 1478       symbol_before_macro_operators:
 1479     mov dl,1Ah
 1480     mov ebx,esi
 1481     lods    byte [esi]
 1482     movzx   ecx,al
 1483     jecxz   symbol_before_macro_operators_ok
 1484     mov edi,esi
 1485     cmp byte [esi],'\'
 1486     je  escaped_symbol
 1487       symbol_before_macro_operators_ok:
 1488     add esi,ecx
 1489     jmp before_macro_operators
 1490       string_before_macro_operators:
 1491     mov dl,22h
 1492     mov ebx,esi
 1493     lods    dword [esi]
 1494     add esi,eax
 1495     jmp before_macro_operators
 1496       escaped_symbol:
 1497     dec byte [edi-1]
 1498     dec ecx
 1499     inc esi
 1500     cmp ecx,1
 1501     rep movs byte [edi],[esi]
 1502     jne after_macro_operators
 1503     mov al,[esi-1]
 1504     mov ecx,ebx
 1505     mov ebx,characters
 1506     xlat    byte [ebx]
 1507     mov ebx,ecx
 1508     or  al,al
 1509     jnz after_macro_operators
 1510     sub edi,3
 1511     mov al,[esi-1]
 1512     stos    byte [edi]
 1513     xor dl,dl
 1514     jmp after_macro_operators
 1515       reduce_symbol_conversion:
 1516     inc esi
 1517       symbol_conversion:
 1518     mov edx,esi
 1519     mov al,[esi]
 1520     cmp al,1Ah
 1521     jne symbol_character_conversion
 1522     lods    word [esi]
 1523     movzx   ecx,ah
 1524     lea ebx,[edi+3]
 1525     jecxz   convert_to_quoted_string
 1526     cmp byte [esi],'\'
 1527     jne convert_to_quoted_string
 1528     inc esi
 1529     dec ecx
 1530     dec ebx
 1531     jmp convert_to_quoted_string
 1532       symbol_character_conversion:
 1533     cmp al,22h
 1534     je  after_macro_operators
 1535     cmp al,'`'
 1536     je  reduce_symbol_conversion
 1537     lea ebx,[edi+5]
 1538     xor ecx,ecx
 1539     or  al,al
 1540     jz  convert_to_quoted_string
 1541     cmp al,'#'
 1542     je  convert_to_quoted_string
 1543     inc ecx
 1544       convert_to_quoted_string:
 1545     sub ebx,edx
 1546     ja  shift_line_data
 1547     mov al,22h
 1548     mov dl,al
 1549     stos    byte [edi]
 1550     mov ebx,edi
 1551     mov eax,ecx
 1552     stos    dword [edi]
 1553     rep movs byte [edi],[esi]
 1554     cmp edi,esi
 1555     je  before_macro_operators
 1556     jmp after_macro_operators
 1557       shift_line_data:
 1558     push    ecx
 1559     mov edx,esi
 1560     lea esi,[ebp-1]
 1561     add ebp,ebx
 1562     lea edi,[ebp-1]
 1563     lea ecx,[esi+1]
 1564     sub ecx,edx
 1565     std
 1566     rep movs byte [edi],[esi]
 1567     cld
 1568     pop eax
 1569     sub edi,3
 1570     mov dl,22h
 1571     mov [edi-1],dl
 1572     mov ebx,edi
 1573     mov [edi],eax
 1574     lea esi,[edi+4+eax]
 1575     jmp before_macro_operators
 1576       concatenation:
 1577     cmp dl,1Ah
 1578     je  symbol_concatenation
 1579     cmp dl,22h
 1580     je  string_concatenation
 1581       no_concatenation:
 1582     cmp esi,edi
 1583     je  before_macro_operators
 1584     jmp after_macro_operators
 1585       symbol_concatenation:
 1586     cmp byte [esi],1Ah
 1587     jne no_concatenation
 1588     inc esi
 1589     lods    byte [esi]
 1590     movzx   ecx,al
 1591     jecxz   do_symbol_concatenation
 1592     cmp byte [esi],'\'
 1593     je  concatenate_escaped_symbol
 1594       do_symbol_concatenation:
 1595     add [ebx],cl
 1596     jc  name_too_long
 1597     rep movs byte [edi],[esi]
 1598     jmp after_macro_operators
 1599       concatenate_escaped_symbol:
 1600     inc esi
 1601     dec ecx
 1602     jz  do_symbol_concatenation
 1603     movzx   eax,byte [esi]
 1604     cmp byte [characters+eax],0
 1605     jne do_symbol_concatenation
 1606     sub esi,3
 1607     jmp no_concatenation
 1608       string_concatenation:
 1609     cmp byte [esi],22h
 1610     je  do_string_concatenation
 1611     cmp byte [esi],'`'
 1612     jne no_concatenation
 1613       concatenate_converted_symbol:
 1614     inc esi
 1615     mov al,[esi]
 1616     cmp al,'`'
 1617     je  concatenate_converted_symbol
 1618     cmp al,22h
 1619     je  do_string_concatenation
 1620     cmp al,1Ah
 1621     jne concatenate_converted_symbol_character
 1622     inc esi
 1623     lods    byte [esi]
 1624     movzx   ecx,al
 1625     jecxz   finish_concatenating_converted_symbol
 1626     cmp byte [esi],'\'
 1627     jne finish_concatenating_converted_symbol
 1628     inc esi
 1629     dec ecx
 1630       finish_concatenating_converted_symbol:
 1631     add [ebx],ecx
 1632     rep movs byte [edi],[esi]
 1633     jmp after_macro_operators
 1634       concatenate_converted_symbol_character:
 1635     or  al,al
 1636     jz  after_macro_operators
 1637     cmp al,'#'
 1638     je  after_macro_operators
 1639     inc dword [ebx]
 1640     movs    byte [edi],[esi]
 1641     jmp after_macro_operators
 1642       do_string_concatenation:
 1643     inc esi
 1644     lods    dword [esi]
 1645     mov ecx,eax
 1646     add [ebx],eax
 1647     rep movs byte [edi],[esi]
 1648       after_macro_operators:
 1649     lods    byte [esi]
 1650     cmp al,'`'
 1651     je  symbol_conversion
 1652     cmp al,'#'
 1653     je  concatenation
 1654     stos    byte [edi]
 1655     cmp al,1Ah
 1656     je  symbol_after_macro_operators
 1657     cmp al,3Bh
 1658     je  no_more_macro_operators
 1659     cmp al,22h
 1660     je  string_after_macro_operators
 1661     xor dl,dl
 1662     or  al,al
 1663     jnz after_macro_operators
 1664     ret
 1665       symbol_after_macro_operators:
 1666     mov dl,1Ah
 1667     mov ebx,edi
 1668     lods    byte [esi]
 1669     stos    byte [edi]
 1670     movzx   ecx,al
 1671     jecxz   symbol_after_macro_operatorss_ok
 1672     cmp byte [esi],'\'
 1673     je  escaped_symbol
 1674       symbol_after_macro_operatorss_ok:
 1675     rep movs byte [edi],[esi]
 1676     jmp after_macro_operators
 1677       string_after_macro_operators:
 1678     mov dl,22h
 1679     mov ebx,edi
 1680     lods    dword [esi]
 1681     stos    dword [edi]
 1682     mov ecx,eax
 1683     rep movs byte [edi],[esi]
 1684     jmp after_macro_operators
 1685 
 1686 use_macro:
 1687     push    [free_additional_memory]
 1688     push    [macro_symbols]
 1689     mov [macro_symbols],0
 1690     push    [counter_limit]
 1691     push    dword [edx+4]
 1692     mov dword [edx+4],1
 1693     push    edx
 1694     mov ebx,esi
 1695     mov esi,[edx+8]
 1696     mov eax,[edx+12]
 1697     mov [macro_line],eax
 1698     mov [counter_limit],0
 1699     xor ebp,ebp
 1700       process_macro_arguments:
 1701     mov al,[esi]
 1702     or  al,al
 1703     jz  arguments_end
 1704     cmp al,'{'
 1705     je  arguments_end
 1706     inc esi
 1707     cmp al,'['
 1708     jne get_macro_arguments
 1709     mov ebp,esi
 1710     inc esi
 1711     inc [counter_limit]
 1712       get_macro_arguments:
 1713     call    get_macro_argument
 1714     lods    byte [esi]
 1715     cmp al,','
 1716     je  next_argument
 1717     cmp al,']'
 1718     je  next_arguments_group
 1719     cmp al,'&'
 1720     je  arguments_end
 1721     dec esi
 1722     jmp arguments_end
 1723       next_argument:
 1724     cmp byte [ebx],','
 1725     jne process_macro_arguments
 1726     inc ebx
 1727     jmp process_macro_arguments
 1728       next_arguments_group:
 1729     cmp byte [ebx],','
 1730     jne arguments_end
 1731     inc ebx
 1732     inc [counter_limit]
 1733     mov esi,ebp
 1734     jmp process_macro_arguments
 1735       get_macro_argument:
 1736     lods    byte [esi]
 1737     movzx   ecx,al
 1738     mov eax,[counter_limit]
 1739     call    add_macro_symbol
 1740     add esi,ecx
 1741     xor eax,eax
 1742     mov [default_argument_value],eax
 1743     cmp byte [esi],'*'
 1744     je  required_value
 1745     cmp byte [esi],':'
 1746     je  get_default_value
 1747     cmp byte [esi],'='
 1748     jne default_value_ok
 1749       get_default_value:
 1750     inc esi
 1751     mov [default_argument_value],esi
 1752     or  [skip_default_argument_value],-1
 1753     call    skip_macro_argument_value
 1754     jmp default_value_ok
 1755       required_value:
 1756     inc esi
 1757     or  [default_argument_value],-1
 1758       default_value_ok:
 1759     xchg    esi,ebx
 1760     mov [edx+12],esi
 1761     mov [skip_default_argument_value],0
 1762     cmp byte [ebx],'&'
 1763     je  greedy_macro_argument
 1764     call    skip_macro_argument_value
 1765     call    finish_macro_argument
 1766     jmp got_macro_argument
 1767       greedy_macro_argument:
 1768     call    skip_foreign_line
 1769     dec esi
 1770     mov eax,[edx+12]
 1771     mov ecx,esi
 1772     sub ecx,eax
 1773     mov [edx+8],ecx
 1774       got_macro_argument:
 1775     xchg    esi,ebx
 1776     cmp dword [edx+8],0
 1777     jne macro_argument_ok
 1778     mov eax,[default_argument_value]
 1779     or  eax,eax
 1780     jz  macro_argument_ok
 1781     cmp eax,-1
 1782     je  invalid_macro_arguments
 1783     mov [edx+12],eax
 1784     call    finish_macro_argument
 1785       macro_argument_ok:
 1786     ret
 1787       finish_macro_argument:
 1788     mov eax,[edx+12]
 1789     mov ecx,esi
 1790     sub ecx,eax
 1791     cmp byte [eax],'<'
 1792     jne argument_value_length_ok
 1793     inc dword [edx+12]
 1794     sub ecx,2
 1795     or  ecx,80000000h
 1796       argument_value_length_ok:
 1797     mov [edx+8],ecx
 1798     ret
 1799       arguments_end:
 1800     cmp byte [ebx],0
 1801     jne invalid_macro_arguments
 1802     mov eax,[esp+4]
 1803     dec eax
 1804     call    process_macro
 1805     pop edx
 1806     pop dword [edx+4]
 1807     pop [counter_limit]
 1808     pop [macro_symbols]
 1809     pop [free_additional_memory]
 1810     jmp line_preprocessed
 1811 use_instant_macro:
 1812     push    edi [current_line] esi
 1813     mov eax,[error_line]
 1814     mov [current_line],eax
 1815     mov [macro_line],eax
 1816     mov esi,[instant_macro_start]
 1817     cmp [base_code],10h
 1818     jae do_match
 1819     cmp [base_code],0
 1820     jne do_irp
 1821     call    precalculate_value
 1822     cmp eax,0
 1823     jl  value_out_of_range
 1824     push    [free_additional_memory]
 1825     push    [macro_symbols]
 1826     mov [macro_symbols],0
 1827     push    [counter_limit]
 1828     mov [struc_name],0
 1829     mov [counter_limit],eax
 1830     lods    byte [esi]
 1831     or  al,al
 1832     jz  rept_counters_ok
 1833     cmp al,'{'
 1834     je  rept_counters_ok
 1835     cmp al,1Ah
 1836     jne invalid_macro_arguments
 1837       add_rept_counter:
 1838     lods    byte [esi]
 1839     movzx   ecx,al
 1840     xor eax,eax
 1841     call    add_macro_symbol
 1842     add esi,ecx
 1843     xor eax,eax
 1844     mov dword [edx+12],eax
 1845     inc eax
 1846     mov dword [edx+8],eax
 1847     lods    byte [esi]
 1848     cmp al,':'
 1849     jne rept_counter_added
 1850     push    edx
 1851     call    precalculate_value
 1852     mov edx,eax
 1853     add edx,[counter_limit]
 1854     jo  value_out_of_range
 1855     pop edx
 1856     mov dword [edx+8],eax
 1857     lods    byte [esi]
 1858       rept_counter_added:
 1859     cmp al,','
 1860     jne rept_counters_ok
 1861     lods    byte [esi]
 1862     cmp al,1Ah
 1863     jne invalid_macro_arguments
 1864     jmp add_rept_counter
 1865       rept_counters_ok:
 1866     dec esi
 1867     cmp [counter_limit],0
 1868     je  instant_macro_finish
 1869       instant_macro_parameters_ok:
 1870     xor eax,eax
 1871     call    process_macro
 1872       instant_macro_finish:
 1873     pop [counter_limit]
 1874     pop [macro_symbols]
 1875     pop [free_additional_memory]
 1876       instant_macro_done:
 1877     pop ebx esi edx
 1878     cmp byte [ebx],0
 1879     je  line_preprocessed
 1880     mov [current_line],edi
 1881     mov ecx,4
 1882     rep movs dword [edi],[esi]
 1883     test    [macro_status],0Fh
 1884     jz  instant_macro_attached_line
 1885     mov ax,3Bh
 1886     stos    word [edi]
 1887       instant_macro_attached_line:
 1888     mov esi,ebx
 1889     sub edx,ebx
 1890     mov ecx,edx
 1891     call    move_data
 1892     jmp initial_preprocessing_ok
 1893       precalculate_value:
 1894     push    edi
 1895     call    convert_expression
 1896     mov al,')'
 1897     stosb
 1898     push    esi
 1899     mov esi,[esp+4]
 1900     mov [error_line],0
 1901     mov [value_size],0
 1902     call    calculate_expression
 1903     cmp [error_line],0
 1904     je  value_precalculated
 1905     jmp [error]
 1906       value_precalculated:
 1907     mov eax,[edi]
 1908     mov ecx,[edi+4]
 1909     cdq
 1910     cmp edx,ecx
 1911     jne value_out_of_range
 1912     cmp dl,[edi+13]
 1913     jne value_out_of_range
 1914     pop esi edi
 1915     ret
 1916 do_irp:
 1917     cmp byte [esi],1Ah
 1918     jne invalid_macro_arguments
 1919     movzx   eax,byte [esi+1]
 1920     lea esi,[esi+2+eax]
 1921     lods    byte [esi]
 1922     cmp [base_code],1
 1923     ja  irps_name_ok
 1924     cmp al,':'
 1925     je  irp_with_default_value
 1926     cmp al,'='
 1927     je  irp_with_default_value
 1928     cmp al,'*'
 1929     jne irp_name_ok
 1930     lods    byte [esi]
 1931       irp_name_ok:
 1932     cmp al,','
 1933     jne invalid_macro_arguments
 1934     jmp irp_parameters_start
 1935       irp_with_default_value:
 1936     xor ebp,ebp
 1937     or  [skip_default_argument_value],-1
 1938     call    skip_macro_argument_value
 1939     cmp byte [esi],','
 1940     jne invalid_macro_arguments
 1941     inc esi
 1942     jmp irp_parameters_start
 1943       irps_name_ok:
 1944     cmp al,','
 1945     jne invalid_macro_arguments
 1946     cmp [base_code],3
 1947     je  irp_parameters_start
 1948     mov al,[esi]
 1949     or  al,al
 1950     jz  instant_macro_done
 1951     cmp al,'{'
 1952     je  instant_macro_done
 1953       irp_parameters_start:
 1954     xor eax,eax
 1955     push    [free_additional_memory]
 1956     push    [macro_symbols]
 1957     mov [macro_symbols],eax
 1958     push    [counter_limit]
 1959     mov [counter_limit],eax
 1960     mov [struc_name],eax
 1961     cmp [base_code],3
 1962     je  get_irpv_parameter
 1963     mov ebx,esi
 1964     cmp [base_code],2
 1965     je  get_irps_parameter
 1966     mov edx,[parameters_end]
 1967     mov al,[edx]
 1968     push    eax
 1969     mov byte [edx],0
 1970       get_irp_parameter:
 1971     inc [counter_limit]
 1972     mov esi,[instant_macro_start]
 1973     inc esi
 1974     call    get_macro_argument
 1975     cmp byte [ebx],','
 1976     jne irp_parameters_end
 1977     inc ebx
 1978     jmp get_irp_parameter
 1979       irp_parameters_end:
 1980     mov esi,ebx
 1981     pop eax
 1982     mov [esi],al
 1983     jmp instant_macro_parameters_ok
 1984       get_irps_parameter:
 1985     mov esi,[instant_macro_start]
 1986     inc esi
 1987     lods    byte [esi]
 1988     movzx   ecx,al
 1989     inc [counter_limit]
 1990     mov eax,[counter_limit]
 1991     call    add_macro_symbol
 1992     mov [edx+12],ebx
 1993     cmp byte [ebx],1Ah
 1994     je  irps_symbol
 1995     cmp byte [ebx],22h
 1996     je  irps_quoted_string
 1997     mov eax,1
 1998     jmp irps_parameter_ok
 1999       irps_quoted_string:
 2000     mov eax,[ebx+1]
 2001     add eax,1+4
 2002     jmp irps_parameter_ok
 2003       irps_symbol:
 2004     movzx   eax,byte [ebx+1]
 2005     add eax,1+1
 2006       irps_parameter_ok:
 2007     mov [edx+8],eax
 2008     add ebx,eax
 2009     cmp byte [ebx],0
 2010     je  irps_parameters_end
 2011     cmp byte [ebx],'{'
 2012     jne get_irps_parameter
 2013       irps_parameters_end:
 2014     mov esi,ebx
 2015     jmp instant_macro_parameters_ok
 2016       get_irpv_parameter:
 2017     lods    byte [esi]
 2018     cmp al,1Ah
 2019     jne invalid_macro_arguments
 2020     lods    byte [esi]
 2021     mov ebp,esi
 2022     mov cl,al
 2023     mov ch,10b
 2024     call    get_preprocessor_symbol
 2025     jc  instant_macro_finish
 2026     push    edx
 2027       mark_variable_value:
 2028     inc [counter_limit]
 2029     mov [edx+4],ebp
 2030       next_variable_value:
 2031     mov edx,[edx]
 2032     or  edx,edx
 2033     jz  variable_values_marked
 2034     mov eax,[edx+4]
 2035     cmp eax,1
 2036     jbe next_variable_value
 2037     mov esi,ebp
 2038     movzx   ecx,byte [esi-1]
 2039     xchg    edi,eax
 2040     repe    cmps byte [esi],[edi]
 2041     xchg    edi,eax
 2042     je  mark_variable_value
 2043     jmp next_variable_value
 2044       variable_values_marked:
 2045     pop edx
 2046     push    [counter_limit]
 2047       add_irpv_value:
 2048     push    edx
 2049     mov esi,[instant_macro_start]
 2050     inc esi
 2051     lods    byte [esi]
 2052     movzx   ecx,al
 2053     mov eax,[esp+4]
 2054     call    add_macro_symbol
 2055     mov ebx,edx
 2056     pop edx
 2057     mov ecx,[edx+12]
 2058     mov eax,[edx+8]
 2059     mov [ebx+12],eax
 2060     mov [ebx+8],ecx
 2061       collect_next_variable_value:
 2062     mov edx,[edx]
 2063     or  edx,edx
 2064     jz  variable_values_collected
 2065     cmp ebp,[edx+4]
 2066     jne collect_next_variable_value
 2067     dec dword [esp]
 2068     jnz add_irpv_value
 2069       variable_values_collected:
 2070     pop eax
 2071     mov esi,ebp
 2072     movzx   ecx,byte [esi-1]
 2073     add esi,ecx
 2074     cmp byte [esi],0
 2075     je  instant_macro_parameters_ok
 2076     cmp byte [esi],'{'
 2077     jne invalid_macro_arguments
 2078     jmp instant_macro_parameters_ok
 2079 
 2080 do_match:
 2081     mov ebx,esi
 2082     call    skip_pattern
 2083     call    exact_match
 2084     mov edx,edi
 2085     mov al,[ebx]
 2086     cmp al,1Ah
 2087     je  free_match
 2088     cmp al,','
 2089     jne instant_macro_done
 2090     cmp esi,[parameters_end]
 2091     je  matched_pattern
 2092     jmp instant_macro_done
 2093       free_match:
 2094     add edx,12
 2095     cmp edx,[memory_end]
 2096     ja  out_of_memory
 2097     mov [edx-12],ebx
 2098     mov [edx-8],esi
 2099     call    skip_match_element
 2100     jc  try_different_matching
 2101     mov [edx-4],esi
 2102     movzx   eax,byte [ebx+1]
 2103     lea ebx,[ebx+2+eax]
 2104     cmp byte [ebx],1Ah
 2105     je  free_match
 2106       find_exact_match:
 2107     call    exact_match
 2108     cmp esi,[parameters_end]
 2109     je  end_matching
 2110     cmp byte [ebx],1Ah
 2111     je  free_match
 2112     mov ebx,[edx-12]
 2113     movzx   eax,byte [ebx+1]
 2114     lea ebx,[ebx+2+eax]
 2115     mov esi,[edx-4]
 2116     jmp match_more_elements
 2117       try_different_matching:
 2118     sub edx,12
 2119     cmp edx,edi
 2120     je  instant_macro_done
 2121     mov ebx,[edx-12]
 2122     movzx   eax,byte [ebx+1]
 2123     lea ebx,[ebx+2+eax]
 2124     cmp byte [ebx],1Ah
 2125     je  try_different_matching
 2126     mov esi,[edx-4]
 2127       match_more_elements:
 2128     call    skip_match_element
 2129     jc  try_different_matching
 2130     mov [edx-4],esi
 2131     jmp find_exact_match
 2132       skip_match_element:
 2133     cmp esi,[parameters_end]
 2134     je  cannot_match
 2135     mov al,[esi]
 2136     cmp al,1Ah
 2137     je  skip_match_symbol
 2138     cmp al,22h
 2139     je  skip_match_quoted_string
 2140     add esi,1
 2141     ret
 2142       skip_match_quoted_string:
 2143     mov eax,[esi+1]
 2144     add esi,5
 2145     jmp skip_match_ok
 2146       skip_match_symbol:
 2147     movzx   eax,byte [esi+1]
 2148     add esi,2
 2149       skip_match_ok:
 2150     add esi,eax
 2151     ret
 2152       cannot_match:
 2153     stc
 2154     ret
 2155       exact_match:
 2156     cmp esi,[parameters_end]
 2157     je  exact_match_complete
 2158     mov ah,[esi]
 2159     mov al,[ebx]
 2160     cmp al,','
 2161     je  exact_match_complete
 2162     cmp al,1Ah
 2163     je  exact_match_complete
 2164     cmp al,'='
 2165     je  match_verbatim
 2166     call    match_elements
 2167     je  exact_match
 2168       exact_match_complete:
 2169     ret
 2170       match_verbatim:
 2171     inc ebx
 2172     call    match_elements
 2173     je  exact_match
 2174     dec ebx
 2175     ret
 2176       match_elements:
 2177     mov al,[ebx]
 2178     cmp al,1Ah
 2179     je  match_symbols
 2180     cmp al,22h
 2181     je  match_quoted_strings
 2182     cmp al,ah
 2183     je  symbol_characters_matched
 2184     ret
 2185       symbol_characters_matched:
 2186     lea ebx,[ebx+1]
 2187     lea esi,[esi+1]
 2188     ret
 2189       match_quoted_strings:
 2190     mov ecx,[ebx+1]
 2191     add ecx,5
 2192     jmp compare_elements
 2193       match_symbols:
 2194     movzx   ecx,byte [ebx+1]
 2195     add ecx,2
 2196       compare_elements:
 2197     mov eax,esi
 2198     mov ebp,edi
 2199     mov edi,ebx
 2200     repe    cmps byte [esi],[edi]
 2201     jne elements_mismatch
 2202     mov ebx,edi
 2203     mov edi,ebp
 2204     ret
 2205       elements_mismatch:
 2206     mov esi,eax
 2207     mov edi,ebp
 2208     ret
 2209       end_matching:
 2210     cmp byte [ebx],','
 2211     jne instant_macro_done
 2212       matched_pattern:
 2213     xor eax,eax
 2214     push    [free_additional_memory]
 2215     push    [macro_symbols]
 2216     mov [macro_symbols],eax
 2217     push    [counter_limit]
 2218     mov [counter_limit],eax
 2219     mov [struc_name],eax
 2220     push    esi edi edx
 2221       add_matched_symbol:
 2222     cmp edi,[esp]
 2223     je  matched_symbols_ok
 2224     mov esi,[edi]
 2225     inc esi
 2226     lods    byte [esi]
 2227     movzx   ecx,al
 2228     xor eax,eax
 2229     call    add_macro_symbol
 2230     mov eax,[edi+4]
 2231     mov dword [edx+12],eax
 2232     mov ecx,[edi+8]
 2233     sub ecx,eax
 2234     mov dword [edx+8],ecx
 2235     add edi,12
 2236     jmp add_matched_symbol
 2237       matched_symbols_ok:
 2238     pop edx edi esi
 2239     jmp instant_macro_parameters_ok
 2240 
 2241 process_macro:
 2242     push    dword [macro_status]
 2243     or  [macro_status],10h
 2244     push    [counter]
 2245     push    [macro_block]
 2246     push    [macro_block_line]
 2247     push    [macro_block_line_number]
 2248     push    [struc_label]
 2249     push    [struc_name]
 2250     push    eax
 2251     push    [current_line]
 2252     lods    byte [esi]
 2253     cmp al,'{'
 2254     je  macro_instructions_start
 2255     or  al,al
 2256     jnz unexpected_characters
 2257       find_macro_instructions:
 2258     mov [macro_line],esi
 2259     add esi,16+2
 2260     lods    byte [esi]
 2261     or  al,al
 2262     jz  find_macro_instructions
 2263     cmp al,'{'
 2264     je  macro_instructions_start
 2265     cmp al,3Bh
 2266     jne unexpected_characters
 2267     call    skip_foreign_symbol
 2268     jmp find_macro_instructions
 2269       macro_instructions_start:
 2270     mov ecx,80000000h
 2271     mov [macro_block],esi
 2272     mov eax,[macro_line]
 2273     mov [macro_block_line],eax
 2274     mov [macro_block_line_number],ecx
 2275     xor eax,eax
 2276     mov [counter],eax
 2277     cmp [counter_limit],eax
 2278     je  process_macro_line
 2279     inc [counter]
 2280       process_macro_line:
 2281     lods    byte [esi]
 2282     or  al,al
 2283     jz  process_next_line
 2284     cmp al,'}'
 2285     je  macro_block_processed
 2286     dec esi
 2287     mov [current_line],edi
 2288     lea eax,[edi+10h]
 2289     cmp eax,[memory_end]
 2290     jae out_of_memory
 2291     mov eax,[esp+4]
 2292     or  eax,eax
 2293     jz  instant_macro_line_header
 2294     stos    dword [edi]
 2295     mov eax,ecx
 2296     stos    dword [edi]
 2297     mov eax,[esp]
 2298     stos    dword [edi]
 2299     mov eax,[macro_line]
 2300     stos    dword [edi]
 2301     jmp macro_line_header_ok
 2302       instant_macro_line_header:
 2303     mov eax,[esp]
 2304     add eax,16
 2305       find_defining_directive:
 2306     inc eax
 2307     cmp byte [eax-1],3Bh
 2308     je  defining_directive_ok
 2309     cmp byte [eax-1],1Ah
 2310     jne find_defining_directive
 2311     push    eax
 2312     movzx   eax,byte [eax]
 2313     inc eax
 2314     add [esp],eax
 2315     pop eax
 2316     jmp find_defining_directive
 2317       defining_directive_ok:
 2318     stos    dword [edi]
 2319     mov eax,ecx
 2320     stos    dword [edi]
 2321     mov eax,[macro_line]
 2322     stos    dword [edi]
 2323     stos    dword [edi]
 2324       macro_line_header_ok:
 2325     or  [macro_status],20h
 2326     push    ebx ecx
 2327     test    [macro_status],0Fh
 2328     jz  process_macro_line_element
 2329     mov ax,3Bh
 2330     stos    word [edi]
 2331       process_macro_line_element:
 2332     lea eax,[edi+100h]
 2333     cmp eax,[memory_end]
 2334     jae out_of_memory
 2335     lods    byte [esi]
 2336     cmp al,'}'
 2337     je  macro_line_processed
 2338     or  al,al
 2339     jz  macro_line_processed
 2340     cmp al,1Ah
 2341     je  process_macro_symbol
 2342     cmp al,3Bh
 2343     je  macro_foreign_line
 2344     and [macro_status],not 20h
 2345     stos    byte [edi]
 2346     cmp al,22h
 2347     jne process_macro_line_element
 2348       copy_macro_string:
 2349     mov ecx,[esi]
 2350     add ecx,4
 2351     call    move_data
 2352     jmp process_macro_line_element
 2353       process_macro_symbol:
 2354     push    esi edi
 2355     test    [macro_status],20h
 2356     jz  not_macro_directive
 2357     movzx   ecx,byte [esi]
 2358     inc esi
 2359     mov edi,macro_directives
 2360     call    get_directive
 2361     jnc process_macro_directive
 2362     dec esi
 2363     jmp not_macro_directive
 2364       process_macro_directive:
 2365     mov edx,eax
 2366     pop edi eax
 2367     mov byte [edi],0
 2368     inc edi
 2369     pop ecx ebx
 2370     jmp near edx
 2371       not_macro_directive:
 2372     and [macro_status],not 20h
 2373     movzx   ecx,byte [esi]
 2374     inc esi
 2375     mov eax,[counter]
 2376     call    get_macro_symbol
 2377     jnc group_macro_symbol
 2378     xor eax,eax
 2379     cmp [counter],eax
 2380     je  multiple_macro_symbol_values
 2381     call    get_macro_symbol
 2382     jc  not_macro_symbol
 2383       replace_macro_symbol:
 2384     pop edi eax
 2385     mov ecx,[edx+8]
 2386     mov edx,[edx+12]
 2387     or  edx,edx
 2388     jz  replace_macro_counter
 2389     and ecx,not 80000000h
 2390     xchg    esi,edx
 2391     call    move_data
 2392     mov esi,edx
 2393     jmp process_macro_line_element
 2394       group_macro_symbol:
 2395     xor eax,eax
 2396     cmp [counter],eax
 2397     je  replace_macro_symbol
 2398     push    esi edx
 2399     sub esi,ecx
 2400     call    get_macro_symbol
 2401     mov ebx,edx
 2402     pop edx esi
 2403     jc  replace_macro_symbol
 2404     cmp edx,ebx
 2405     ja  replace_macro_symbol
 2406     mov edx,ebx
 2407     jmp replace_macro_symbol
 2408       multiple_macro_symbol_values:
 2409     inc eax
 2410     push    eax
 2411     call    get_macro_symbol
 2412     pop eax
 2413     jc  not_macro_symbol
 2414     pop edi
 2415     push    ecx
 2416     mov ecx,[edx+8]
 2417     mov edx,[edx+12]
 2418     xchg    esi,edx
 2419     btr ecx,31
 2420     jc  enclose_macro_symbol_value
 2421     rep movs byte [edi],[esi]
 2422     jmp macro_symbol_value_ok
 2423       enclose_macro_symbol_value:
 2424     mov byte [edi],'<'
 2425     inc edi
 2426     rep movs byte [edi],[esi]
 2427     mov byte [edi],'>'
 2428     inc edi
 2429       macro_symbol_value_ok:
 2430     cmp eax,[counter_limit]
 2431     je  multiple_macro_symbol_values_ok
 2432     mov byte [edi],','
 2433     inc edi
 2434     mov esi,edx
 2435     pop ecx
 2436     push    edi
 2437     sub esi,ecx
 2438     jmp multiple_macro_symbol_values
 2439       multiple_macro_symbol_values_ok:
 2440     pop ecx eax
 2441     mov esi,edx
 2442     jmp process_macro_line_element
 2443       replace_macro_counter:
 2444     mov eax,[counter]
 2445     and eax,not 80000000h
 2446     jz  group_macro_counter
 2447     add ecx,eax
 2448     dec ecx
 2449     call    store_number_symbol
 2450     jmp process_macro_line_element
 2451       group_macro_counter:
 2452     mov edx,ecx
 2453     xor ecx,ecx
 2454       multiple_macro_counter_values:
 2455     push    ecx edx
 2456     add ecx,edx
 2457     call    store_number_symbol
 2458     pop edx ecx
 2459     inc ecx
 2460     cmp ecx,[counter_limit]
 2461     je  process_macro_line_element
 2462     mov byte [edi],','
 2463     inc edi
 2464     jmp multiple_macro_counter_values
 2465       store_number_symbol:
 2466     cmp ecx,0
 2467     jge numer_symbol_sign_ok
 2468     neg ecx
 2469     mov al,'-'
 2470     stos    byte [edi]
 2471       numer_symbol_sign_ok:
 2472     mov ax,1Ah
 2473     stos    word [edi]
 2474     push    edi
 2475     mov eax,ecx
 2476     mov ecx,1000000000
 2477     xor edx,edx
 2478     xor bl,bl
 2479       store_number_digits:
 2480     div ecx
 2481     push    edx
 2482     or  bl,bl
 2483     jnz store_number_digit
 2484     cmp ecx,1
 2485     je  store_number_digit
 2486     or  al,al
 2487     jz  number_digit_ok
 2488     not bl
 2489       store_number_digit:
 2490     add al,30h
 2491     stos    byte [edi]
 2492       number_digit_ok:
 2493     mov eax,ecx
 2494     xor edx,edx
 2495     mov ecx,10
 2496     div ecx
 2497     mov ecx,eax
 2498     pop eax
 2499     or  ecx,ecx
 2500     jnz store_number_digits
 2501     pop ebx
 2502     mov eax,edi
 2503     sub eax,ebx
 2504     mov [ebx-1],al
 2505     ret
 2506       not_macro_symbol:
 2507     pop edi esi
 2508     mov al,1Ah
 2509     stos    byte [edi]
 2510     mov al,[esi]
 2511     inc esi
 2512     stos    byte [edi]
 2513     cmp byte [esi],'.'
 2514     jne copy_raw_symbol
 2515     mov ebx,[esp+8+8]
 2516     or  ebx,ebx
 2517     jz  copy_raw_symbol
 2518     cmp al,1
 2519     je  copy_struc_name
 2520     xchg    esi,ebx
 2521     movzx   ecx,byte [esi-1]
 2522     add [edi-1],cl
 2523     jc  name_too_long
 2524     rep movs byte [edi],[esi]
 2525     xchg    esi,ebx
 2526       copy_raw_symbol:
 2527     movzx   ecx,al
 2528     rep movs byte [edi],[esi]
 2529     jmp process_macro_line_element
 2530       copy_struc_name:
 2531     inc esi
 2532     xchg    esi,ebx
 2533     movzx   ecx,byte [esi-1]
 2534     mov [edi-1],cl
 2535     rep movs byte [edi],[esi]
 2536     xchg    esi,ebx
 2537     mov eax,[esp+8+12]
 2538     cmp byte [eax],3Bh
 2539     je  process_macro_line_element
 2540     cmp byte [eax],1Ah
 2541     jne disable_replaced_struc_name
 2542     mov byte [eax],3Bh
 2543     jmp process_macro_line_element
 2544       disable_replaced_struc_name:
 2545     mov ebx,[esp+8+8]
 2546     push    esi edi
 2547     lea edi,[ebx-3]
 2548     lea esi,[edi-2]
 2549     lea ecx,[esi+1]
 2550     sub ecx,eax
 2551     std
 2552     rep movs byte [edi],[esi]
 2553     cld
 2554     mov word [eax],3Bh
 2555     pop edi esi
 2556     jmp process_macro_line_element
 2557       skip_foreign_symbol:
 2558     lods    byte [esi]
 2559     movzx   eax,al
 2560     add esi,eax
 2561       skip_foreign_line:
 2562     lods    byte [esi]
 2563     cmp al,1Ah
 2564     je  skip_foreign_symbol
 2565     cmp al,3Bh
 2566     je  skip_foreign_symbol
 2567     cmp al,22h
 2568     je  skip_foreign_string
 2569     or  al,al
 2570     jnz skip_foreign_line
 2571     ret
 2572       skip_foreign_string:
 2573     lods    dword [esi]
 2574     add esi,eax
 2575     jmp skip_foreign_line
 2576       macro_foreign_line:
 2577     call    skip_foreign_symbol
 2578       macro_line_processed:
 2579     mov byte [edi],0
 2580     inc edi
 2581     push    eax
 2582     call    preprocess_line
 2583     pop eax
 2584     pop ecx ebx
 2585     cmp al,'}'
 2586     je  macro_block_processed
 2587       process_next_line:
 2588     inc ecx
 2589     mov [macro_line],esi
 2590     add esi,16+2
 2591     jmp process_macro_line
 2592       macro_block_processed:
 2593     call    close_macro_block
 2594     jc  process_macro_line
 2595     pop [current_line]
 2596     add esp,12
 2597     pop [macro_block_line_number]
 2598     pop [macro_block_line]
 2599     pop [macro_block]
 2600     pop [counter]
 2601     pop eax
 2602     and al,0F0h
 2603     and [macro_status],0Fh
 2604     or  [macro_status],al
 2605     ret
 2606 
 2607 local_symbols:
 2608     lods    byte [esi]
 2609     cmp al,1Ah
 2610     jne invalid_argument
 2611     mov byte [edi-1],3Bh
 2612     xor al,al
 2613     stos    byte [edi]
 2614       make_local_symbol:
 2615     push    ecx
 2616     lods    byte [esi]
 2617     movzx   ecx,al
 2618     mov eax,[counter]
 2619     call    add_macro_symbol
 2620     mov [edx+12],edi
 2621     movzx   eax,[locals_counter]
 2622     add eax,ecx
 2623     inc eax
 2624     cmp eax,100h
 2625     jae name_too_long
 2626     lea ebp,[edi+2+eax]
 2627     cmp ebp,[memory_end]
 2628     jae out_of_memory
 2629     mov ah,al
 2630     mov al,1Ah
 2631     stos    word [edi]
 2632     rep movs byte [edi],[esi]
 2633     mov al,'?'
 2634     stos    byte [edi]
 2635     push    esi
 2636     mov esi,locals_counter+1
 2637     movzx   ecx,[locals_counter]
 2638     rep movs byte [edi],[esi]
 2639     pop esi
 2640     mov eax,edi
 2641     sub eax,[edx+12]
 2642     mov [edx+8],eax
 2643     xor al,al
 2644     stos    byte [edi]
 2645     mov eax,locals_counter
 2646     movzx   ecx,byte [eax]
 2647       counter_loop:
 2648     inc byte [eax+ecx]
 2649     cmp byte [eax+ecx],'9'+1
 2650     jb  counter_ok
 2651     jne letter_digit
 2652     mov byte [eax+ecx],'A'
 2653     jmp counter_ok
 2654       letter_digit:
 2655     cmp byte [eax+ecx],'Z'+1
 2656     jb  counter_ok
 2657     jne small_letter_digit
 2658     mov byte [eax+ecx],'a'
 2659     jmp counter_ok
 2660       small_letter_digit:
 2661     cmp byte [eax+ecx],'z'+1
 2662     jb  counter_ok
 2663     mov byte [eax+ecx],'0'
 2664     loop    counter_loop
 2665     inc byte [eax]
 2666     movzx   ecx,byte [eax]
 2667     mov byte [eax+ecx],'0'
 2668       counter_ok:
 2669     pop ecx
 2670     lods    byte [esi]
 2671     cmp al,'}'
 2672     je  macro_block_processed
 2673     or  al,al
 2674     jz  process_next_line
 2675     cmp al,','
 2676     jne extra_characters_on_line
 2677     dec edi
 2678     lods    byte [esi]
 2679     cmp al,1Ah
 2680     je  make_local_symbol
 2681     jmp invalid_argument
 2682 common_block:
 2683     call    close_macro_block
 2684     jc  process_macro_line
 2685     mov [counter],0
 2686     jmp new_macro_block
 2687 forward_block:
 2688     cmp [counter_limit],0
 2689     je  common_block
 2690     call    close_macro_block
 2691     jc  process_macro_line
 2692     mov [counter],1
 2693     jmp new_macro_block
 2694 reverse_block:
 2695     cmp [counter_limit],0
 2696     je  common_block
 2697     call    close_macro_block
 2698     jc  process_macro_line
 2699     mov eax,[counter_limit]
 2700     or  eax,80000000h
 2701     mov [counter],eax
 2702       new_macro_block:
 2703     mov [macro_block],esi
 2704     mov eax,[macro_line]
 2705     mov [macro_block_line],eax
 2706     mov [macro_block_line_number],ecx
 2707     jmp process_macro_line
 2708 close_macro_block:
 2709     cmp esi,[macro_block]
 2710     je  block_closed
 2711     cmp [counter],0
 2712     je  block_closed
 2713     jl  reverse_counter
 2714     mov eax,[counter]
 2715     cmp eax,[counter_limit]
 2716     je  block_closed
 2717     inc [counter]
 2718     jmp continue_block
 2719       reverse_counter:
 2720     mov eax,[counter]
 2721     dec eax
 2722     cmp eax,80000000h
 2723     je  block_closed
 2724     mov [counter],eax
 2725       continue_block:
 2726     mov esi,[macro_block]
 2727     mov eax,[macro_block_line]
 2728     mov [macro_line],eax
 2729     mov ecx,[macro_block_line_number]
 2730     stc
 2731     ret
 2732       block_closed:
 2733     clc
 2734     ret
 2735 get_macro_symbol:
 2736     push    ecx
 2737     call    find_macro_symbol_leaf
 2738     jc  macro_symbol_not_found
 2739     mov edx,[ebx]
 2740     mov ebx,esi
 2741       try_macro_symbol:
 2742     or  edx,edx
 2743     jz  macro_symbol_not_found
 2744     mov ecx,[esp]
 2745     mov edi,[edx+4]
 2746     repe    cmps byte [esi],[edi]
 2747     je  macro_symbol_found
 2748     mov esi,ebx
 2749     mov edx,[edx]
 2750     jmp try_macro_symbol
 2751       macro_symbol_found:
 2752     pop ecx
 2753     clc
 2754     ret
 2755       macro_symbol_not_found:
 2756     pop ecx
 2757     stc
 2758     ret
 2759       find_macro_symbol_leaf:
 2760     shl eax,8
 2761     mov al,cl
 2762     mov ebp,eax
 2763     mov ebx,macro_symbols
 2764       follow_macro_symbols_tree:
 2765     mov edx,[ebx]
 2766     or  edx,edx
 2767     jz  no_such_macro_symbol
 2768     xor eax,eax
 2769     shr ebp,1
 2770     adc eax,0
 2771     lea ebx,[edx+eax*4]
 2772     or  ebp,ebp
 2773     jnz follow_macro_symbols_tree
 2774     add ebx,8
 2775     clc
 2776     ret
 2777       no_such_macro_symbol:
 2778     stc
 2779     ret
 2780 add_macro_symbol:
 2781     push    ebx ebp
 2782     call    find_macro_symbol_leaf
 2783     jc  extend_macro_symbol_tree
 2784     mov eax,[ebx]
 2785       make_macro_symbol:
 2786     mov edx,[free_additional_memory]
 2787     add edx,16
 2788     cmp edx,[labels_list]
 2789     ja  out_of_memory
 2790     xchg    edx,[free_additional_memory]
 2791     mov [ebx],edx
 2792     mov [edx],eax
 2793     mov [edx+4],esi
 2794     pop ebp ebx
 2795     ret
 2796       extend_macro_symbol_tree:
 2797     mov edx,[free_additional_memory]
 2798     add edx,16
 2799     cmp edx,[labels_list]
 2800     ja  out_of_memory
 2801     xchg    edx,[free_additional_memory]
 2802     xor eax,eax
 2803     mov [edx],eax
 2804     mov [edx+4],eax
 2805     mov [edx+8],eax
 2806     mov [edx+12],eax
 2807     shr ebp,1
 2808     adc eax,0
 2809     mov [ebx],edx
 2810     lea ebx,[edx+eax*4]
 2811     or  ebp,ebp
 2812     jnz extend_macro_symbol_tree
 2813     add ebx,8
 2814     xor eax,eax
 2815     jmp make_macro_symbol
 2816 
 2817 include_file:
 2818     lods    byte [esi]
 2819     cmp al,22h
 2820     jne invalid_argument
 2821     lods    dword [esi]
 2822     cmp byte [esi+eax],0
 2823     jne extra_characters_on_line
 2824     push    esi
 2825     push    edi
 2826     mov ebx,[current_line]
 2827       find_current_file_path:
 2828     mov esi,[ebx]
 2829     test    byte [ebx+7],80h
 2830     jz  copy_current_file_path
 2831     mov ebx,[ebx+8]
 2832     jmp find_current_file_path
 2833       copy_current_file_path:
 2834     lods    byte [esi]
 2835     stos    byte [edi]
 2836     or  al,al
 2837     jnz copy_current_file_path
 2838       cut_current_file_name:
 2839     cmp edi,[esp]
 2840     je  current_file_path_ok
 2841     cmp byte [edi-1],'\'
 2842     je  current_file_path_ok
 2843     cmp byte [edi-1],'/'
 2844     je  current_file_path_ok
 2845     dec edi
 2846     jmp cut_current_file_name
 2847       current_file_path_ok:
 2848     mov esi,[esp+4]
 2849     call    expand_path
 2850     pop edx
 2851     mov esi,edx
 2852     call    open
 2853     jnc include_path_ok
 2854     mov ebp,[include_paths]
 2855       try_include_directories:
 2856     mov edi,esi
 2857     mov esi,ebp
 2858     cmp byte [esi],0
 2859     je  try_in_current_directory
 2860     push    ebp
 2861     push    edi
 2862     call    get_include_directory
 2863     mov [esp+4],esi
 2864     mov esi,[esp+8]
 2865     call    expand_path
 2866     pop edx
 2867     mov esi,edx
 2868     call    open
 2869     pop ebp
 2870     jnc include_path_ok
 2871     jmp try_include_directories
 2872     mov edi,esi
 2873       try_in_current_directory:
 2874     mov esi,[esp]
 2875     push    edi
 2876     call    expand_path
 2877     pop edx
 2878     mov esi,edx
 2879     call    open
 2880     jc  file_not_found
 2881       include_path_ok:
 2882     mov edi,[esp]
 2883       copy_preprocessed_path:
 2884     lods    byte [esi]
 2885     stos    byte [edi]
 2886     or  al,al
 2887     jnz copy_preprocessed_path
 2888     pop esi
 2889     lea ecx,[edi-1]
 2890     sub ecx,esi
 2891     mov [esi-4],ecx
 2892     push    dword [macro_status]
 2893     and [macro_status],0Fh
 2894     call    preprocess_file
 2895     pop eax
 2896     and al,0F0h
 2897     and [macro_status],0Fh
 2898     or  [macro_status],al
 2899     jmp line_preprocessed