Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. ; flat assembler core
  3. ; Copyright (c) 1999-2005, 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.         push    [memory_end]
  17.         mov     esi,[memory_start]
  18.         mov     edi,[source_start]
  19.       parser_loop:
  20.         mov     [current_line],esi
  21.         lea     eax,[edi+100h]
  22.         cmp     eax,[memory_end]
  23.         jae     out_of_memory
  24.         cmp     byte [esi+16],0
  25.         je      empty_line
  26.         mov     al,0Fh
  27.         stos    byte [edi]
  28.         mov     eax,esi
  29.         stos    dword [edi]
  30.         add     esi,16
  31.         call    parse_line
  32.       parse_next_line:
  33.         cmp     esi,[source_start]
  34.         jb      parser_loop
  35.         xor     al,al
  36.         stos    byte [edi]
  37.         mov     eax,[error_line]
  38.         mov     [current_line],eax
  39.         cmp     [anonymous_forward],0
  40.         jne     invalid_value
  41.         add     edi,0Fh
  42.         and     edi,not 0Fh
  43.         mov     [code_start],edi
  44.         pop     [memory_end]
  45.         ret
  46.       empty_line:
  47.         add     esi,17
  48.         jmp     parse_next_line
  49.  
  50. parse_line:
  51.         mov     [parenthesis_stack],0
  52.       instruction_start:
  53.         cmp     byte [esi],1Ah
  54.         jne     empty_instruction
  55.         push    edi
  56.         add     esi,2
  57.         movzx   ecx,byte [esi-1]
  58.         cmp     byte [esi+ecx],':'
  59.         je      simple_label
  60.         cmp     byte [esi+ecx],'='
  61.         je      constant_label
  62.         cmp     byte [esi+ecx],1Ah
  63.         jne     get_main_instruction
  64.         push    esi ecx
  65.         lea     esi,[esi+ecx+2]
  66.         movzx   ecx,byte [esi-1]
  67.         mov     edi,data_directives
  68.         call    get_symbol
  69.         jnc     data_label
  70.         pop     ecx esi
  71.       get_main_instruction:
  72.         call    get_instruction
  73.         jnc     parse_instruction
  74.         mov     edi,data_directives
  75.         call    get_symbol
  76.         jnc     data_instruction
  77.         mov     edi,symbols
  78.         call    get_symbol
  79.         pop     edi
  80.         jc      unknown_instruction
  81.         stos    word [edi]
  82.         jmp     parse_arguments
  83.       data_instruction:
  84.         movzx   ebx,ah
  85.         mov     bx,[data_handlers+ebx*2]
  86.         jmp     parse_instruction
  87.       unknown_instruction:
  88.         sub     esi,2
  89.         jmp     parse_arguments
  90.       constant_label:
  91.         pop     edi
  92.         call    get_label_id
  93.         mov     byte [edi],3
  94.         inc     edi
  95.         stos    dword [edi]
  96.         xor     al,al
  97.         stos    byte [edi]
  98.         inc     esi
  99.         jmp     parse_arguments
  100.       data_label:
  101.         pop     ecx ebx
  102.         pop     edi
  103.         push    eax esi
  104.         mov     esi,ebx
  105.         movzx   ecx,byte [esi-1]
  106.         call    identify_label
  107.         mov     byte [edi],2
  108.         inc     edi
  109.         stos    dword [edi]
  110.         pop     esi eax
  111.         stos    byte [edi]
  112.         push    edi
  113.         jmp     data_instruction
  114.       simple_label:
  115.         pop     edi
  116.         call    identify_label
  117.         mov     byte [edi],2
  118.         inc     edi
  119.         stos    dword [edi]
  120.         inc     esi
  121.         xor     al,al
  122.         stos    byte [edi]
  123.         jmp     instruction_start
  124.       identify_label:
  125.         cmp     byte [esi],'.'
  126.         je      local_label_name
  127.         call    get_label_id
  128.         cmp     eax,10h
  129.         jb      label_identified
  130.         or      ebx,ebx
  131.         jz      anonymous_label_name
  132.         dec     ebx
  133.         mov     [current_locals_prefix],ebx
  134.       label_identified:
  135.         ret
  136.       anonymous_label_name:
  137.         cmp     byte [esi-1],'@'
  138.         je      anonymous_label_name_ok
  139.         mov     eax,0Fh
  140.       anonymous_label_name_ok:
  141.         ret
  142.       local_label_name:
  143.         call    get_label_id
  144.         ret
  145.       parse_label_directive:
  146.         cmp     byte [esi],1Ah
  147.         jne     argument_parsed
  148.         inc     esi
  149.         movzx   ecx,byte [esi]
  150.         inc     esi
  151.         mov     al,2
  152.         stos    byte [edi]
  153.         call    identify_label
  154.         stos    dword [edi]
  155.         xor     al,al
  156.         stos    byte [edi]
  157.         jmp     argument_parsed
  158.       parse_load_directive:
  159.         cmp     byte [esi],1Ah
  160.         jne     argument_parsed
  161.         inc     esi
  162.         movzx   ecx,byte [esi]
  163.         inc     esi
  164.         mov     al,2
  165.         stos    byte [edi]
  166.         call    get_label_id
  167.         stos    dword [edi]
  168.         xor     al,al
  169.         stos    byte [edi]
  170.         jmp     argument_parsed
  171.       parse_prefix_instruction:
  172.         cmp     byte [esi],1Ah
  173.         jne     parse_arguments
  174.         push    edi
  175.         inc     esi
  176.         movzx   ecx,byte [esi]
  177.         inc     esi
  178.         jmp     get_main_instruction
  179.       parse_instruction:
  180.         pop     edi
  181.         mov     dl,al
  182.         mov     al,1
  183.         stos    byte [edi]
  184.         mov     ax,bx
  185.         stos    word [edi]
  186.         mov     al,dl
  187.         stos    byte [edi]
  188.         cmp     bx,prefix_instruction-assembler
  189.         je      parse_prefix_instruction
  190.         cmp     bx,end_directive-assembler
  191.         je      parse_prefix_instruction
  192.         cmp     bx,label_directive-assembler
  193.         je      parse_label_directive
  194.         cmp     bx,segment_directive-assembler
  195.         je      parse_label_directive
  196.         cmp     bx,load_directive-assembler
  197.         je      parse_load_directive
  198.         cmp     bx,extrn_directive-assembler
  199.         je      parse_extrn_directive
  200.         cmp     bx,public_directive-assembler
  201.         je      parse_public_directive
  202.       parse_arguments:
  203.         lods    byte [esi]
  204.         cmp     al,':'
  205.         je      instruction_separator
  206.         cmp     al,','
  207.         je      separator
  208.         cmp     al,'='
  209.         je      separator
  210.         cmp     al,'|'
  211.         je      separator
  212.         cmp     al,'&'
  213.         je      separator
  214.         cmp     al,'~'
  215.         je      separator
  216.         cmp     al,'>'
  217.         je      greater
  218.         cmp     al,'<'
  219.         je      less
  220.         cmp     al,')'
  221.         je      close_parenthesis
  222.         or      al,al
  223.         jz      line_parsed
  224.         cmp     al,'['
  225.         je      address_argument
  226.         cmp     al,']'
  227.         je      separator
  228.         cmp     al,'{'
  229.         je      unallowed_character
  230.         cmp     al,'}'
  231.         je      unallowed_character
  232.         cmp     al,'#'
  233.         je      unallowed_character
  234.         cmp     al,'`'
  235.         je      unallowed_character
  236.         dec     esi
  237.         cmp     al,1Ah
  238.         jne     expression_argument
  239.         push    edi
  240.         mov     edi,directive_operators
  241.         call    get_operator
  242.         or      al,al
  243.         jnz     operator_argument
  244.         inc     esi
  245.         movzx   ecx,byte [esi]
  246.         inc     esi
  247.         mov     edi,symbols
  248.         call    get_symbol
  249.         jnc     symbol_argument
  250.         mov     edi,formatter_symbols
  251.         call    get_symbol
  252.         jnc     symbol_argument
  253.         cmp     ecx,1
  254.         jne     check_argument
  255.         cmp     byte [esi],'?'
  256.         jne     check_argument
  257.         pop     edi
  258.         movs    byte [edi],[esi]
  259.         jmp     argument_parsed
  260.       symbol_argument:
  261.         pop     edi
  262.         stos    word [edi]
  263.         jmp     argument_parsed
  264.       operator_argument:
  265.         pop     edi
  266.         cmp     al,85h
  267.         je      ptr_argument
  268.         stos    byte [edi]
  269.         cmp     al,80h
  270.         je      forced_expression
  271.         cmp     al,81h
  272.         je      forced_parenthesis
  273.         cmp     al,82h
  274.         je      parse_from_operator
  275.         cmp     al,89h
  276.         je      parse_label_operator
  277.         jmp     argument_parsed
  278.       parse_public_directive:
  279.         cmp     byte [esi],1Ah
  280.         jne     parse_arguments
  281.         inc     esi
  282.         push    esi
  283.         movzx   ecx,byte [esi]
  284.         inc     esi
  285.         mov     al,2
  286.         stos    byte [edi]
  287.         call    get_label_id
  288.         stos    dword [edi]
  289.         mov     ax,8600h
  290.         stos    word [edi]
  291.         pop     ebx
  292.         push    ebx esi edi
  293.         mov     edi,directive_operators
  294.         call    get_operator
  295.         pop     edi edx ebx
  296.         cmp     al,86h
  297.         je      argument_parsed
  298.         mov     esi,edx
  299.         xchg    esi,ebx
  300.         movzx   ecx,byte [esi]
  301.         inc     esi
  302.         mov     ax,'('
  303.         stos    word [edi]
  304.         mov     eax,ecx
  305.         stos    dword [edi]
  306.         rep     movs byte [edi],[esi]
  307.         xor     al,al
  308.         stos    byte [edi]
  309.         xchg    esi,ebx
  310.         jmp     argument_parsed
  311.       parse_extrn_directive:
  312.         cmp     byte [esi],22h
  313.         je      parse_quoted_extrn
  314.         cmp     byte [esi],1Ah
  315.         jne     parse_arguments
  316.         push    esi
  317.         movzx   ecx,byte [esi+1]
  318.         add     esi,2
  319.         mov     ax,'('
  320.         stos    word [edi]
  321.         mov     eax,ecx
  322.         stos    dword [edi]
  323.         rep     movs byte [edi],[esi]
  324.         mov     ax,8600h
  325.         stos    word [edi]
  326.         pop     esi
  327.       parse_label_operator:
  328.         cmp     byte [esi],1Ah
  329.         jne     argument_parsed
  330.         inc     esi
  331.         movzx   ecx,byte [esi]
  332.         inc     esi
  333.         mov     al,2
  334.         stos    byte [edi]
  335.         call    get_label_id
  336.         stos    dword [edi]
  337.         xor     al,al
  338.         stos    byte [edi]
  339.         jmp     argument_parsed
  340.       parse_from_operator:
  341.         cmp     byte [esi],22h
  342.         jne     forced_expression
  343.         jmp     argument_parsed
  344.       parse_quoted_extrn:
  345.         inc     esi
  346.         mov     ax,'('
  347.         stos    word [edi]
  348.         lods    dword [esi]
  349.         mov     ecx,eax
  350.         stos    dword [edi]
  351.         rep     movs byte [edi],[esi]
  352.         xor     al,al
  353.         stos    byte [edi]
  354.         push    esi edi
  355.         mov     edi,directive_operators
  356.         call    get_operator
  357.         mov     edx,esi
  358.         pop     edi esi
  359.         cmp     al,86h
  360.         jne     argument_parsed
  361.         stos    byte [edi]
  362.         mov     esi,edx
  363.         jmp     parse_label_operator
  364.       ptr_argument:
  365.         call    parse_address
  366.         jmp     address_parsed
  367.       check_argument:
  368.         push    esi ecx
  369.         sub     esi,2
  370.         mov     edi,single_operand_operators
  371.         call    get_operator
  372.         pop     ecx esi
  373.         or      al,al
  374.         jnz     not_instruction
  375.         call    get_instruction
  376.         jnc     parse_instruction
  377.         mov     edi,data_directives
  378.         call    get_symbol
  379.         jnc     data_instruction
  380.       not_instruction:
  381.         pop     edi
  382.         sub     esi,2
  383.       expression_argument:
  384.         cmp     byte [esi],22h
  385.         jne     not_string
  386.         mov     eax,[esi+1]
  387.         lea     ebx,[esi+5+eax]
  388.         push    ebx ecx esi edi
  389.         mov     al,'('
  390.         stos    byte [edi]
  391.         call    convert_expression
  392.         mov     al,')'
  393.         stos    byte [edi]
  394.         pop     eax edx ecx ebx
  395.         cmp     esi,ebx
  396.         jne     expression_parsed
  397.         mov     edi,eax
  398.         mov     esi,edx
  399.       string_argument:
  400.         inc     esi
  401.         mov     ax,'('
  402.         stos    word [edi]
  403.         lods    dword [esi]
  404.         mov     ecx,eax
  405.         stos    dword [edi]
  406.         shr     ecx,1
  407.         jnc     string_movsb_ok
  408.         movs    byte [edi],[esi]
  409.       string_movsb_ok:
  410.         shr     ecx,1
  411.         jnc     string_movsw_ok
  412.         movs    word [edi],[esi]
  413.       string_movsw_ok:
  414.         rep     movs dword [edi],[esi]
  415.         xor     al,al
  416.         stos    byte [edi]
  417.         jmp     expression_parsed
  418.       not_string:
  419.         cmp     byte [esi],'('
  420.         jne     expression
  421.         mov     eax,esp
  422.         sub     eax,100h
  423.         jc      stack_overflow
  424.         cmp     eax,[stack_limit]
  425.         jb      stack_overflow
  426.         push    esi edi
  427.         inc     esi
  428.         mov     al,'{'
  429.         stos    byte [edi]
  430.         inc     [parenthesis_stack]
  431.         jmp     parse_arguments
  432.       expression:
  433.         mov     al,'('
  434.         stos    byte [edi]
  435.         call    convert_expression
  436.         mov     al,')'
  437.         stos    byte [edi]
  438.         jmp     expression_parsed
  439.       forced_expression:
  440.         mov     al,'('
  441.         stos    byte [edi]
  442.         call    convert_expression
  443.         mov     al,')'
  444.         stos    byte [edi]
  445.         jmp     argument_parsed
  446.       address_argument:
  447.         call    parse_address
  448.         lods    byte [esi]
  449.         cmp     al,']'
  450.         jne     invalid_address
  451.       address_parsed:
  452.         mov     al,']'
  453.         stos    byte [edi]
  454.         jmp     argument_parsed
  455.       parse_address:
  456.         mov     al,'['
  457.         stos    byte [edi]
  458.         cmp     word [esi],021Ah
  459.         jne     convert_address
  460.         push    esi
  461.         add     esi,4
  462.         lea     ebx,[esi+1]
  463.         cmp     byte [esi],':'
  464.         pop     esi
  465.         jne     convert_address
  466.         add     esi,2
  467.         mov     ecx,2
  468.         push    ebx edi
  469.         mov     edi,symbols
  470.         call    get_symbol
  471.         pop     edi esi
  472.         jc      invalid_address
  473.         cmp     al,10h
  474.         jne     invalid_address
  475.         mov     al,ah
  476.         and     ah,11110000b
  477.         cmp     ah,60h
  478.         jne     invalid_address
  479.         stos    byte [edi]
  480.       convert_address:
  481.         cmp     byte [esi],1Ah
  482.         jne     convert_expression
  483.         push    esi
  484.         lods    word [esi]
  485.         movzx   ecx,ah
  486.         push    edi
  487.         mov     edi,address_sizes
  488.         call    get_symbol
  489.         pop     edi
  490.         jc      no_size_prefix
  491.         mov     al,ah
  492.         add     al,70h
  493.         stos    byte [edi]
  494.         add     esp,4
  495.         jmp     convert_expression
  496.       no_size_prefix:
  497.         pop     esi
  498.         jmp     convert_expression
  499.       forced_parenthesis:
  500.         cmp     byte [esi],'('
  501.         jne     argument_parsed
  502.         inc     esi
  503.         mov     al,'{'
  504.         jmp     separator
  505.       unallowed_character:
  506.         mov     al,0FFh
  507.         jmp     separator
  508.       close_parenthesis:
  509.         mov     al,'}'
  510.       separator:
  511.         stos    byte [edi]
  512.         jmp     argument_parsed
  513.       instruction_separator:
  514.         stos    byte [edi]
  515.         jmp     instruction_start
  516.       greater:
  517.         cmp     byte [esi],'='
  518.         jne     separator
  519.         inc     esi
  520.         mov     al,0F2h
  521.         jmp     separator
  522.       less:
  523.         cmp     byte [edi-1],0F6h
  524.         je      separator
  525.         cmp     byte [esi],'>'
  526.         je      not_equal
  527.         cmp     byte [esi],'='
  528.         jne     separator
  529.         inc     esi
  530.         mov     al,0F3h
  531.         jmp     separator
  532.       not_equal:
  533.         inc     esi
  534.         mov     al,0F1h
  535.         jmp     separator
  536.       argument_parsed:
  537.         cmp     [parenthesis_stack],0
  538.         je      parse_arguments
  539.         dec     [parenthesis_stack]
  540.         add     esp,8
  541.         jmp     argument_parsed
  542.       expression_parsed:
  543.         cmp     [parenthesis_stack],0
  544.         je      parse_arguments
  545.         cmp     byte [esi],')'
  546.         jne     argument_parsed
  547.         dec     [parenthesis_stack]
  548.         pop     edi esi
  549.         jmp     expression
  550.       empty_instruction:
  551.         lods    byte [esi]
  552.         or      al,al
  553.         jz      line_parsed
  554.         cmp     al,':'
  555.         je      invalid_name
  556.         cmp     al,3Bh
  557.         je      skip_preprocessed_symbol
  558.         dec     esi
  559.         jmp     parse_arguments
  560.       skip_preprocessed_symbol:
  561.         lods    byte [esi]
  562.         movzx   eax,al
  563.         add     esi,eax
  564.       skip_next:
  565.         lods    byte [esi]
  566.         or      al,al
  567.         jz      line_parsed
  568.         cmp     al,1Ah
  569.         je      skip_preprocessed_symbol
  570.         cmp     al,3Bh
  571.         je      skip_preprocessed_symbol
  572.         cmp     al,22h
  573.         je      skip_preprocessed_string
  574.         jmp     skip_next
  575.       skip_preprocessed_string:
  576.         lods    dword [esi]
  577.         add     esi,eax
  578.         jmp     skip_next
  579.       line_parsed:
  580.         cmp     [parenthesis_stack],0
  581.         jne     invalid_expression
  582.         ret
  583.  
  584. get_operator:
  585.         cmp     byte [esi],1Ah
  586.         jne     get_simple_operator
  587.         mov     edx,esi
  588.         push    ebp
  589.         inc     esi
  590.         lods    byte [esi]
  591.         movzx   ebp,al
  592.         push    edi
  593.         mov     ecx,ebp
  594.         call    lower_case
  595.         pop     edi
  596.       check_operator:
  597.         mov     esi,converted
  598.         movzx   ecx,byte [edi]
  599.         jecxz   no_operator
  600.         inc     edi
  601.         mov     ebx,edi
  602.         add     ebx,ecx
  603.         cmp     ecx,ebp
  604.         jne     next_operator
  605.         repe    cmps byte [esi],[edi]
  606.         je      operator_found
  607.       next_operator:
  608.         mov     edi,ebx
  609.         inc     edi
  610.         jmp     check_operator
  611.       no_operator:
  612.         mov     esi,edx
  613.         mov     ecx,ebp
  614.         pop     ebp
  615.       no_simple_operator:
  616.         xor     al,al
  617.         ret
  618.       operator_found:
  619.         lea     esi,[edx+2+ebp]
  620.         mov     ecx,ebp
  621.         pop     ebp
  622.         mov     al,[edi]
  623.         ret
  624.       get_simple_operator:
  625.         mov     al,[esi]
  626.         cmp     al,22h
  627.         je      no_simple_operator
  628.       simple_operator:
  629.         cmp     byte [edi],1
  630.         jb      no_simple_operator
  631.         ja      simple_next_operator
  632.         cmp     al,[edi+1]
  633.         je      simple_operator_found
  634.       simple_next_operator:
  635.         movzx   ecx,byte [edi]
  636.         lea     edi,[edi+1+ecx+1]
  637.         jmp     simple_operator
  638.       simple_operator_found:
  639.         inc     esi
  640.         mov     al,[edi+2]
  641.         ret
  642.  
  643.  
  644. get_symbol:
  645.         mov     edx,esi
  646.         mov     ebp,ecx
  647.         push    edi
  648.         call    lower_case
  649.         pop     edi
  650.       scan_symbols:
  651.         mov     esi,converted
  652.         movzx   eax,byte [edi]
  653.         or      al,al
  654.         jz      no_symbol
  655.         mov     ecx,ebp
  656.         inc     edi
  657.         mov     ebx,edi
  658.         add     ebx,eax
  659.         mov     ah,[esi]
  660.         cmp     ah,[edi]
  661.         jb      no_symbol
  662.         ja      next_symbol
  663.         cmp     cl,al
  664.         jne     next_symbol
  665.         repe    cmps byte [esi],[edi]
  666.         jb      no_symbol
  667.         je      symbol_ok
  668.       next_symbol:
  669.         mov     edi,ebx
  670.         add     edi,2
  671.         jmp     scan_symbols
  672.       no_symbol:
  673.         mov     esi,edx
  674.         mov     ecx,ebp
  675.         stc
  676.         ret
  677.       symbol_ok:
  678.         lea     esi,[edx+ebp]
  679.         mov     ax,[ebx]
  680.         clc
  681.         ret
  682.  
  683. get_instruction:
  684.         mov     edx,esi
  685.         mov     ebp,ecx
  686.         call    lower_case
  687.         mov     ecx,ebp
  688.         cmp     cl,11
  689.         ja      no_instruction
  690.         sub     cl,2
  691.         jc      no_instruction
  692.         movzx   edi,word [instructions+ecx*2]
  693.         add     edi,instructions
  694.       scan_instructions:
  695.         mov     esi,converted
  696.         mov     al,[edi]
  697.         or      al,al
  698.         jz      no_instruction
  699.         mov     ecx,ebp
  700.         mov     ebx,edi
  701.         add     ebx,ecx
  702.         repe    cmps byte [esi],[edi]
  703.         jb      no_instruction
  704.         je      instruction_ok
  705.       next_instruction:
  706.         mov     edi,ebx
  707.         add     edi,3
  708.         jmp     scan_instructions
  709.       no_instruction:
  710.         mov     esi,edx
  711.         mov     ecx,ebp
  712.         stc
  713.         ret
  714.       lower_case:
  715.         mov     edi,converted
  716.         mov     ebx,characters
  717.       convert_case:
  718.         lods    byte [esi]
  719.         xlat    byte [ebx]
  720.         stos    byte [edi]
  721.         loop    convert_case
  722.       case_ok:
  723.         ret
  724.       instruction_ok:
  725.         lea     esi,[edx+ebp]
  726.         mov     al,[ebx]
  727.         mov     bx,[ebx+1]
  728.         clc
  729.         ret
  730.  
  731. get_label_id:
  732.         cmp     ecx,100h
  733.         jae     name_too_long
  734.         cmp     byte [esi],'@'
  735.         je      anonymous_label
  736.         cmp     byte [esi],'.'
  737.         jne     standard_label
  738.         cmp     byte [esi+1],'.'
  739.         je      standard_label
  740.         cmp     [current_locals_prefix],0
  741.         je      standard_label
  742.         push    edi
  743.         mov     edi,[memory_end]
  744.         sub     edi,2
  745.         sub     edi,ecx
  746.         push    ecx esi
  747.         mov     esi,[current_locals_prefix]
  748.         lods    byte [esi]
  749.         movzx   ecx,al
  750.         sub     edi,ecx
  751.         cmp     edi,[esp+8]
  752.         jb      out_of_memory
  753.         mov     [memory_end],edi
  754.         mov     word [edi],0
  755.         add     edi,2
  756.         mov     ebx,edi
  757.         rep     movs byte [edi],[esi]
  758.         pop     esi ecx
  759.         add     al,cl
  760.         jc      name_too_long
  761.         rep     movs byte [edi],[esi]
  762.         pop     edi
  763.         push    esi
  764.         movzx   ecx,al
  765.         mov     byte [ebx-1],al
  766.         mov     esi,ebx
  767.         call    get_label_id
  768.         pop     esi
  769.         ret
  770.       anonymous_label:
  771.         cmp     ecx,2
  772.         jne     standard_label
  773.         mov     al,[esi+1]
  774.         mov     ebx,characters
  775.         xlat    byte [ebx]
  776.         cmp     al,'@'
  777.         je      new_anonymous
  778.         cmp     al,'b'
  779.         je      anonymous_back
  780.         cmp     al,'r'
  781.         je      anonymous_back
  782.         cmp     al,'f'
  783.         jne     standard_label
  784.         add     esi,2
  785.         mov     eax,[anonymous_forward]
  786.         or      eax,eax
  787.         jnz     anonymous_ok
  788.         mov     eax,[current_line]
  789.         mov     [error_line],eax
  790.         mov     eax,[labels_list]
  791.         sub     eax,24
  792.         mov     [labels_list],eax
  793.         mov     [anonymous_forward],eax
  794.       anonymous_ok:
  795.         xor     ebx,ebx
  796.         ret
  797.       anonymous_back:
  798.         add     esi,2
  799.         mov     eax,[anonymous_reverse]
  800.         or      eax,eax
  801.         jz      invalid_value
  802.         jmp     anonymous_ok
  803.       new_anonymous:
  804.         add     esi,2
  805.         mov     eax,[anonymous_forward]
  806.         or      eax,eax
  807.         jnz     new_anonymous_ok
  808.         mov     eax,[labels_list]
  809.         sub     eax,24
  810.         mov     [labels_list],eax
  811.       new_anonymous_ok:
  812.         mov     [anonymous_reverse],eax
  813.         mov     [anonymous_forward],0
  814.         jmp     anonymous_ok
  815.       standard_label:
  816.         cmp     byte [esi],'%'
  817.         je      get_predefined_id
  818.         cmp     byte [esi],'$'
  819.         jne     find_label
  820.         cmp     ecx,2
  821.         ja      find_label
  822.         inc     esi
  823.         jb      get_current_offset_id
  824.         inc     esi
  825.         cmp     byte [esi-1],'$'
  826.         je      get_org_origin_id
  827.         sub     esi,ecx
  828.         jmp     find_label
  829.       get_current_offset_id:
  830.         xor     eax,eax
  831.         ret
  832.       get_counter_id:
  833.         mov     eax,1
  834.         ret
  835.       get_timestamp_id:
  836.         mov     eax,2
  837.         ret
  838.       get_org_origin_id:
  839.         mov     eax,3
  840.         ret
  841.       get_predefined_id:
  842.         cmp     ecx,2
  843.         ja      find_label
  844.         inc     esi
  845.         cmp     cl,1
  846.         je      get_counter_id
  847.         lods    byte [esi]
  848.         mov     ebx,characters
  849.         xlat    [ebx]
  850.         cmp     al,'t'
  851.         je      get_timestamp_id
  852.         sub     esi,2
  853.       find_label:
  854.         xor     ebx,ebx
  855.         mov     eax,2166136261
  856.         mov     ebp,16777619
  857.       hash_label:
  858.         xor     al,[esi+ebx]
  859.         mul     ebp
  860.         inc     bl
  861.         cmp     bl,cl
  862.         jb      hash_label
  863.         mov     ebp,eax
  864.         shl     eax,8
  865.         and     ebp,0FFh shl 24
  866.         xor     ebp,eax
  867.         or      ebp,ebx
  868.         mov     [label_hash],ebp
  869.         push    edi esi
  870.         push    ecx
  871.         mov     ecx,32
  872.         mov     ebx,hash_tree
  873.       follow_tree:
  874.         mov     edx,[ebx]
  875.         or      edx,edx
  876.         jz      extend_tree
  877.         xor     eax,eax
  878.         shl     ebp,1
  879.         adc     eax,0
  880.         lea     ebx,[edx+eax*4]
  881.         dec     ecx
  882.         jnz     follow_tree
  883.         mov     [label_leaf],ebx
  884.         pop     edx
  885.         mov     eax,[ebx]
  886.         or      eax,eax
  887.         jz      add_label
  888.         mov     ebx,esi
  889.         mov     ebp,[label_hash]
  890.       compare_labels:
  891.         mov     esi,ebx
  892.         mov     ecx,edx
  893.         mov     edi,[eax+4]
  894.         repe    cmps byte [esi],[edi]
  895.         je      label_found
  896.         mov     eax,[eax]
  897.         or      eax,eax
  898.         jnz     compare_labels
  899.         jmp     add_label
  900.       label_found:
  901.         add     esp,4
  902.         pop     edi
  903.         mov     ebx,[eax+4]
  904.         mov     eax,[eax+8]
  905.         ret
  906.       extend_tree:
  907.         mov     edx,[free_additional_memory]
  908.         lea     eax,[edx+8]
  909.         cmp     eax,[additional_memory_end]
  910.         ja      out_of_memory
  911.         mov     [free_additional_memory],eax
  912.         xor     eax,eax
  913.         mov     [edx],eax
  914.         mov     [edx+4],eax
  915.         shl     ebp,1
  916.         adc     eax,0
  917.         mov     [ebx],edx
  918.         lea     ebx,[edx+eax*4]
  919.         dec     ecx
  920.         jnz     extend_tree
  921.         mov     [label_leaf],ebx
  922.         pop     edx
  923.       add_label:
  924.         mov     ecx,edx
  925.         pop     esi
  926.         cmp     byte [esi-2],0
  927.         je      label_name_ok
  928.         mov     al,[esi]
  929.         cmp     al,30h
  930.         jb      name_first_char_ok
  931.         cmp     al,39h
  932.         jbe     invalid_name
  933.       name_first_char_ok:
  934.         cmp     ecx,1
  935.         jne     check_for_reserved_word
  936.         cmp     al,'$'
  937.         je      reserved_word
  938.       check_for_reserved_word:
  939.         call    get_instruction
  940.         jnc     reserved_word
  941.         mov     edi,data_directives
  942.         call    get_symbol
  943.         jnc     reserved_word
  944.         mov     edi,symbols
  945.         call    get_symbol
  946.         jnc     reserved_word
  947.         mov     edi,formatter_symbols
  948.         call    get_symbol
  949.         jnc     reserved_word
  950.         sub     esi,2
  951.         mov     edi,operators
  952.         call    get_operator
  953.         or      al,al
  954.         jnz     reserved_word
  955.         mov     edi,single_operand_operators
  956.         call    get_operator
  957.         or      al,al
  958.         jnz     reserved_word
  959.         mov     edi,directive_operators
  960.         call    get_operator
  961.         or      al,al
  962.         jnz     reserved_word
  963.         inc     esi
  964.         movzx   ecx,byte [esi]
  965.         inc     esi
  966.       label_name_ok:
  967.         mov     edx,[free_additional_memory]
  968.         lea     eax,[edx+12]
  969.         cmp     eax,[additional_memory_end]
  970.         ja      out_of_memory
  971.         mov     [free_additional_memory],eax
  972.         mov     [edx+4],esi
  973.         mov     ebx,esi
  974.         add     esi,ecx
  975.         mov     eax,[label_leaf]
  976.         mov     edi,[eax]
  977.         mov     [edx],edi
  978.         mov     [eax],edx
  979.         mov     eax,[labels_list]
  980.         sub     eax,24
  981.         mov     [labels_list],eax
  982.         mov     [edx+8],eax
  983.         pop     edi
  984.         ret
  985.       reserved_word:
  986.         mov     eax,0Fh
  987.         pop     edi
  988.         ret
  989.  
  990. operators:
  991.  db 1,'+',80h
  992.  db 1,'-',81h
  993.  db 1,'*',90h
  994.  db 1,'/',91h
  995.  db 3,'mod',0A0h
  996.  db 3,'and',0B0h
  997.  db 2,'or',0B1h
  998.  db 3,'xor',0B2h
  999.  db 3,'shl',0C0h
  1000.  db 3,'shr',0C1h
  1001.  db 0
  1002.  
  1003. single_operand_operators:
  1004.  db 1,'+',0
  1005.  db 1,'-',0D1h
  1006.  db 3,'not',0D0h
  1007.  db 3,'rva',0E0h
  1008.  db 0
  1009.  
  1010. directive_operators:
  1011.  db 2,'as',86h
  1012.  db 2,'at',80h
  1013.  db 7,'defined',88h
  1014.  db 3,'dup',81h
  1015.  db 2,'eq',0F0h
  1016.  db 6,'eqtype',0F7h
  1017.  db 4,'from',82h
  1018.  db 2,'in',0F6h
  1019.  db 2,'on',84h
  1020.  db 3,'ptr',85h
  1021.  db 4,'used',89h
  1022.  db 0
  1023.