"Fossies" - the Fresh Open Source Software Archive

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