Subversion Repositories Kolibri OS

Rev

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

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