Subversion Repositories Kolibri OS

Rev

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

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