Subversion Repositories Kolibri OS

Rev

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

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