Subversion Repositories Kolibri OS

Rev

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

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