Subversion Repositories Kolibri OS

Rev

Rev 2665 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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