Subversion Repositories Kolibri OS

Rev

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

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