Subversion Repositories Kolibri OS

Rev

Rev 2664 | Blame | Last modification | View Log | Download | RSS feed

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