Subversion Repositories Kolibri OS

Rev

Rev 7836 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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