Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. ; flat assembler core
  3. ; Copyright (c) 1999-2005, Tomasz Grysztar.
  4. ; All rights reserved.
  5.  
  6. assembler:
  7.         mov     ecx,[memory_end]
  8.         mov     edi,[labels_list]
  9.         sub     ecx,edi
  10.         cmp     edi,[code_start]
  11.         jbe     out_of_memory
  12.         shr     ecx,2
  13.         xor     eax,eax
  14.         rep     stos dword [edi]
  15.         mov     [stub_size],eax
  16.         mov     [number_of_sections],eax
  17.         mov     [current_pass],ax
  18.       assembler_loop:
  19.         mov     eax,[labels_list]
  20.         mov     [display_buffer],eax
  21.         mov     eax,[additional_memory]
  22.         mov     [free_additional_memory],eax
  23.         mov     eax,[additional_memory_end]
  24.         mov     [structures_buffer],eax
  25.         mov     esi,[source_start]
  26.         mov     edi,[code_start]
  27.         xor     eax,eax
  28.         mov     dword [adjustment],eax
  29.         mov     dword [adjustment+4],eax
  30.         mov     dword [org_origin],edi
  31.         mov     dword [org_origin+4],eax
  32.         mov     [org_start],edi
  33.         mov     [org_registers],eax
  34.         mov     [org_symbol],eax
  35.         mov     [error_line],eax
  36.         mov     [counter],eax
  37.         mov     [format_flags],eax
  38.         mov     [number_of_relocations],eax
  39.         mov     [undefined_data_end],eax
  40.         mov     [next_pass_needed],al
  41.         mov     [output_format],al
  42.         mov     [labels_type],al
  43.         mov     [virtual_data],al
  44.         mov     [code_type],16
  45.       pass_loop:
  46.         call    assemble_line
  47.         jnc     pass_loop
  48.         mov     eax,[additional_memory_end]
  49.         cmp     eax,[structures_buffer]
  50.         je      pass_done
  51.         sub     eax,20h
  52.         mov     eax,[eax+4]
  53.         mov     [current_line],eax
  54.         jmp     missing_end_directive
  55.       pass_done:
  56.         call    close_pass
  57.         mov     eax,[labels_list]
  58.       check_symbols:
  59.         cmp     eax,[memory_end]
  60.         jae     symbols_checked
  61.         test    byte [eax+8],8
  62.         jz      symbol_defined_ok
  63.         mov     cx,[current_pass]
  64.         cmp     cx,[eax+18]
  65.         jne     symbol_defined_ok
  66.         test    byte [eax+8],1
  67.         jz      symbol_defined_ok
  68.         sub     cx,[eax+16]
  69.         cmp     cx,1
  70.         jne     symbol_defined_ok
  71.         and     byte [eax+8],not 1
  72.         or      [next_pass_needed],-1
  73.       symbol_defined_ok:
  74.         test    byte [eax+8],10h
  75.         jz      use_prediction_ok
  76.         mov     cx,[current_pass]
  77.         and     byte [eax+8],not 10h
  78.         test    byte [eax+8],20h
  79.         jnz     check_use_prediction
  80.         cmp     cx,[eax+18]
  81.         jne     use_prediction_ok
  82.         test    byte [eax+8],8
  83.         jz      use_prediction_ok
  84.         jmp     use_misprediction
  85.       check_use_prediction:
  86.         test    byte [eax+8],8
  87.         jz      use_misprediction
  88.         cmp     cx,[eax+18]
  89.         je      use_prediction_ok
  90.       use_misprediction:
  91.         or      [next_pass_needed],-1
  92.       use_prediction_ok:
  93.         test    byte [eax+8],40h
  94.         jz      check_next_symbol
  95.         and     byte [eax+8],not 40h
  96.         test    byte [eax+8],4
  97.         jnz     define_misprediction
  98.         mov     cx,[current_pass]
  99.         test    byte [eax+8],80h
  100.         jnz     check_define_prediction
  101.         cmp     cx,[eax+16]
  102.         jne     check_next_symbol
  103.         test    byte [eax+8],1
  104.         jz      check_next_symbol
  105.         jmp     define_misprediction
  106.       check_define_prediction:
  107.         test    byte [eax+8],1
  108.         jz      define_misprediction
  109.         cmp     cx,[eax+16]
  110.         je      check_next_symbol
  111.       define_misprediction:
  112.         or      [next_pass_needed],-1
  113.       check_next_symbol:
  114.         add     eax,24
  115.         jmp     check_symbols
  116.       symbols_checked:
  117.         cmp     [next_pass_needed],0
  118.         jne     next_pass
  119.         mov     eax,[error_line]
  120.         or      eax,eax
  121.         jz      assemble_ok
  122.         mov     [current_line],eax
  123.         jmp     near [error]
  124.       next_pass:
  125.         inc     [current_pass]
  126.         mov     ax,[current_pass]
  127.         cmp     ax,[passes_limit]
  128.         je      code_cannot_be_generated
  129.         jmp     assembler_loop
  130.       assemble_ok:
  131.         ret
  132.  
  133. assemble_line:
  134.         mov     eax,[display_buffer]
  135.         sub     eax,100h
  136.         cmp     edi,eax
  137.         ja      out_of_memory
  138.         lods    byte [esi]
  139.         cmp     al,1
  140.         je      assemble_instruction
  141.         jb      source_end
  142.         cmp     al,3
  143.         jb      define_label
  144.         je      define_constant
  145.         cmp     al,0Fh
  146.         je      new_line
  147.         cmp     al,13h
  148.         je      code_type_setting
  149.         cmp     al,10h
  150.         jne     illegal_instruction
  151.         lods    byte [esi]
  152.         jmp     segment_prefix
  153.       code_type_setting:
  154.         lods    byte [esi]
  155.         mov     [code_type],al
  156.         jmp     line_assembled
  157.       new_line:
  158.         lods    dword [esi]
  159.         mov     [current_line],eax
  160.         mov     [prefixed_instruction],0
  161.       continue_line:
  162.         cmp     byte [esi],0Fh
  163.         je      line_assembled
  164.         jmp     assemble_line
  165.       define_label:
  166.         lods    dword [esi]
  167.         cmp     eax,0Fh
  168.         jb      invalid_use_of_symbol
  169.         je      reserved_word_used_as_symbol
  170.         mov     ebx,eax
  171.         lods    byte [esi]
  172.         mov     cl,al
  173.         mov     eax,edi
  174.         xor     edx,edx
  175.         sub     eax,dword [org_origin]
  176.         sbb     edx,dword [org_origin+4]
  177.         mov     ch,[labels_type]
  178.         cmp     [virtual_data],0
  179.         jne     make_virtual_label
  180.         or      byte [ebx+9],1
  181.         xchg    eax,[ebx]
  182.         xchg    edx,[ebx+4]
  183.         sub     eax,[ebx]
  184.         sbb     edx,[ebx+4]
  185.         mov     dword [adjustment],eax
  186.         mov     dword [adjustment+4],edx
  187.         or      eax,edx
  188.         setnz   ah
  189.         jmp     finish_label_symbol
  190.       make_virtual_label:
  191.         and     byte [ebx+9],not 1
  192.         cmp     eax,[ebx]
  193.         mov     [ebx],eax
  194.         setne   ah
  195.         cmp     edx,[ebx+4]
  196.         mov     [ebx+4],edx
  197.         setne   al
  198.         or      ah,al
  199.       finish_label_symbol:
  200.         cmp     cl,[ebx+10]
  201.         mov     [ebx+10],cl
  202.         setne   al
  203.         or      ah,al
  204.         cmp     ch,[ebx+11]
  205.         mov     [ebx+11],ch
  206.         setne   al
  207.         or      ah,al
  208.         mov     edx,[org_registers]
  209.         cmp     edx,[ebx+12]
  210.         mov     [ebx+12],edx
  211.         setne   al
  212.         or      ah,al
  213.         or      ch,ch
  214.         jz      label_symbol_ok
  215.         mov     edx,[org_symbol]
  216.         cmp     edx,[ebx+20]
  217.         mov     [ebx+20],edx
  218.         setne   al
  219.         or      ah,al
  220.       label_symbol_ok:
  221.         mov     cx,[current_pass]
  222.         xchg    [ebx+16],cx
  223.         and     byte [ebx+8],not 2
  224.         test    byte [ebx+8],1
  225.         jz      new_label
  226.         cmp     cx,[ebx+16]
  227.         je      symbol_already_defined
  228.         inc     cx
  229.         sub     cx,[ebx+16]
  230.         setnz   al
  231.         or      ah,al
  232.         jz      continue_line
  233.         test    byte [ebx+8],8
  234.         jz      continue_line
  235.         mov     cx,[current_pass]
  236.         cmp     cx,[ebx+18]
  237.         jne     continue_line
  238.         or      [next_pass_needed],-1
  239.         jmp     continue_line
  240.       new_label:
  241.         or      byte [ebx+8],1
  242.         jmp     continue_line
  243.       define_constant:
  244.         lods    dword [esi]
  245.         inc     esi
  246.         cmp     eax,0Fh
  247.         jb      invalid_use_of_symbol
  248.         je      reserved_word_used_as_symbol
  249.         mov     edx,[eax+8]
  250.         push    edx
  251.         cmp     [current_pass],0
  252.         je      get_constant_value
  253.         test    dl,4
  254.         jnz     get_constant_value
  255.         mov     cx,[current_pass]
  256.         cmp     cx,[eax+16]
  257.         je      get_constant_value
  258.         and     dl,not 1
  259.         mov     [eax+8],dl
  260.       get_constant_value:
  261.         push    eax
  262.         mov     al,byte [esi-1]
  263.         push    eax
  264.         call    get_value
  265.         pop     ebx
  266.         mov     ch,bl
  267.         pop     ebx
  268.         pop     dword [ebx+8]
  269.         cmp     ebx,0Fh
  270.         jb      invalid_use_of_symbol
  271.         je      reserved_word_used_as_symbol
  272.         xor     cl,cl
  273.         mov     ch,[value_type]
  274.         cmp     ch,3
  275.         je      invalid_use_of_symbol
  276.       make_constant:
  277.         and     byte [ebx+9],not 1
  278.         cmp     eax,[ebx]
  279.         mov     [ebx],eax
  280.         setne   ah
  281.         cmp     edx,[ebx+4]
  282.         mov     [ebx+4],edx
  283.         setne   al
  284.         or      ah,al
  285.         cmp     cl,[ebx+10]
  286.         mov     [ebx+10],cl
  287.         setne   al
  288.         or      ah,al
  289.         cmp     ch,[ebx+11]
  290.         mov     [ebx+11],ch
  291.         setne   al
  292.         or      ah,al
  293.         xor     edx,edx
  294.         cmp     edx,[ebx+12]
  295.         mov     [ebx+12],edx
  296.         setne   al
  297.         or      ah,al
  298.         or      ch,ch
  299.         jz      constant_symbol_ok
  300.         mov     edx,[symbol_identifier]
  301.         cmp     edx,[ebx+20]
  302.         mov     [ebx+20],edx
  303.         setne   al
  304.         or      ah,al
  305.       constant_symbol_ok:
  306.         mov     cx,[current_pass]
  307.         xchg    [ebx+16],cx
  308.         test    byte [ebx+8],1
  309.         jz      new_constant
  310.         cmp     cx,[ebx+16]
  311.         jne     redeclare_constant
  312.         test    byte [ebx+8],2
  313.         jz      symbol_already_defined
  314.         or      byte [ebx+8],4
  315.         jmp     instruction_assembled
  316.       redeclare_constant:
  317.         inc     cx
  318.         sub     cx,[ebx+16]
  319.         setnz   al
  320.         or      ah,al
  321.         jz      instruction_assembled
  322.         test    byte [ebx+8],4
  323.         jnz     instruction_assembled
  324.         test    byte [ebx+8],8
  325.         jz      instruction_assembled
  326.         mov     cx,[current_pass]
  327.         cmp     cx,[ebx+18]
  328.         jne     instruction_assembled
  329.         or      [next_pass_needed],-1
  330.         jmp     instruction_assembled
  331.       new_constant:
  332.         or      byte [ebx+8],1+2
  333.         jmp     instruction_assembled
  334.       assemble_instruction:
  335.         mov     [operand_size],0
  336.         mov     [size_override],0
  337.         mov     [operand_prefix],0
  338.         mov     [rex_prefix],0
  339.         mov     [immediate_size],0
  340.         movzx   ebx,word [esi]
  341.         mov     al,[esi+2]
  342.         add     ebx,assembler
  343.         add     esi,3
  344.         jmp     near ebx
  345.       instruction_assembled:
  346.         mov     al,[esi]
  347.         cmp     al,0Fh
  348.         je      line_assembled
  349.         or      al,al
  350.         jnz     extra_characters_on_line
  351.       line_assembled:
  352.         clc
  353.         ret
  354.       source_end:
  355.         dec     esi
  356.         stc
  357.         ret
  358. skip_line:
  359.         call    skip_symbol
  360.         jnc     skip_line
  361.         ret
  362. skip_symbol:
  363.         lods    byte [esi]
  364.         or      al,al
  365.         jz      nothing_to_skip
  366.         cmp     al,0Fh
  367.         je      nothing_to_skip
  368.         cmp     al,1
  369.         je      skip_instruction
  370.         cmp     al,2
  371.         je      skip_label
  372.         cmp     al,3
  373.         je      skip_label
  374.         cmp     al,20h
  375.         jb      skip_assembler_symbol
  376.         cmp     al,'('
  377.         je      skip_expression
  378.         cmp     al,'['
  379.         je      skip_address
  380.       skip_done:
  381.         clc
  382.         ret
  383.       skip_label:
  384.         add     esi,2
  385.       skip_instruction:
  386.         add     esi,2
  387.       skip_assembler_symbol:
  388.         inc     esi
  389.         jmp     skip_done
  390.       skip_address:
  391.         mov     al,[esi]
  392.         and     al,11110000b
  393.         cmp     al,60h
  394.         jb      skip_expression
  395.         cmp     al,70h
  396.         ja      skip_expression
  397.         inc     esi
  398.         jmp     skip_address
  399.       skip_expression:
  400.         lods    byte [esi]
  401.         or      al,al
  402.         jz      skip_string
  403.         cmp     al,'.'
  404.         je      skip_fp_value
  405.         cmp     al,')'
  406.         je      skip_done
  407.         cmp     al,']'
  408.         je      skip_done
  409.         cmp     al,0Fh
  410.         je      skip_expression
  411.         cmp     al,10h
  412.         je      skip_register
  413.         cmp     al,11h
  414.         je      skip_label_value
  415.         cmp     al,80h
  416.         jae     skip_expression
  417.         movzx   eax,al
  418.         add     esi,eax
  419.         jmp     skip_expression
  420.       skip_label_value:
  421.         add     esi,3
  422.       skip_register:
  423.         inc     esi
  424.         jmp     skip_expression
  425.       skip_fp_value:
  426.         add     esi,12
  427.         jmp     skip_done
  428.       skip_string:
  429.         lods    dword [esi]
  430.         add     esi,eax
  431.         inc     esi
  432.         jmp     skip_done
  433.       nothing_to_skip:
  434.         dec     esi
  435.         stc
  436.         ret
  437.  
  438. org_directive:
  439.         lods    byte [esi]
  440.         cmp     al,'('
  441.         jne     invalid_argument
  442.         cmp     byte [esi],'.'
  443.         je      invalid_value
  444.         call    get_qword_value
  445.         mov     cl,[value_type]
  446.         test    cl,1
  447.         jnz     invalid_use_of_symbol
  448.         mov     [labels_type],cl
  449.         mov     ecx,edi
  450.         sub     ecx,eax
  451.         sbb     edx,0
  452.         mov     dword [org_origin],ecx
  453.         mov     dword [org_origin+4],edx
  454.         mov     [org_registers],0
  455.         mov     [org_start],edi
  456.         mov     edx,[symbol_identifier]
  457.         mov     [org_symbol],edx
  458.         cmp     [output_format],1
  459.         ja      instruction_assembled
  460.         cmp     edi,[code_start]
  461.         jne     instruction_assembled
  462.         cmp     eax,100h
  463.         jne     instruction_assembled
  464.         bts     [format_flags],0
  465.         jmp     instruction_assembled
  466. label_directive:
  467.         lods    byte [esi]
  468.         cmp     al,2
  469.         jne     invalid_argument
  470.         lods    dword [esi]
  471.         cmp     eax,0Fh
  472.         jb      invalid_use_of_symbol
  473.         je      reserved_word_used_as_symbol
  474.         inc     esi
  475.         mov     ebx,eax
  476.         xor     cl,cl
  477.         lods    byte [esi]
  478.         cmp     al,':'
  479.         je      get_label_size
  480.         dec     esi
  481.         cmp     al,11h
  482.         jne     label_size_ok
  483.       get_label_size:
  484.         lods    word [esi]
  485.         cmp     al,11h
  486.         jne     invalid_argument
  487.         mov     cl,ah
  488.       label_size_ok:
  489.         mov     eax,edi
  490.         xor     edx,edx
  491.         sub     eax,dword [org_origin]
  492.         sbb     edx,dword [org_origin+4]
  493.         mov     ebp,[org_registers]
  494.         cmp     byte [esi],80h
  495.         je      get_free_label_value
  496.         mov     ch,[labels_type]
  497.         push    [org_symbol]
  498.         pop     [address_symbol]
  499.         cmp     [virtual_data],0
  500.         jne     make_free_label
  501.         or      byte [ebx+9],1
  502.         xchg    eax,[ebx]
  503.         xchg    edx,[ebx+4]
  504.         sub     eax,[ebx]
  505.         sbb     edx,[ebx+4]
  506.         mov     dword [adjustment],eax
  507.         mov     dword [adjustment+4],edx
  508.         or      eax,edx
  509.         setne   ah
  510.         jmp     finish_label
  511.       get_free_label_value:
  512.         inc     esi
  513.         lods    byte [esi]
  514.         cmp     al,'('
  515.         jne     invalid_argument
  516.         push    dword [ebx+8]
  517.         push    ebx ecx
  518.         and     byte [ebx+8],not 1
  519.         cmp     byte [esi],'.'
  520.         je      invalid_value
  521.         call    get_address_value
  522.         or      bh,bh
  523.         setnz   ch
  524.         xchg    ch,cl
  525.         mov     bp,cx
  526.         shl     ebp,16
  527.         xchg    bl,bh
  528.         mov     bp,bx
  529.         pop     ecx ebx
  530.         pop     dword [ebx+8]
  531.         mov     ch,[value_type]
  532.         or      ch,ch
  533.         jz      make_free_label
  534.         cmp     ch,2
  535.         jne     invalid_use_of_symbol
  536.       make_free_label:
  537.         and     byte [ebx+9],not 1
  538.         cmp     eax,[ebx]
  539.         mov     [ebx],eax
  540.         setne   ah
  541.         cmp     edx,[ebx+4]
  542.         mov     [ebx+4],edx
  543.         setne   al
  544.         or      ah,al
  545.         jmp     finish_label
  546.       finish_label:
  547.         cmp     cl,[ebx+10]
  548.         mov     [ebx+10],cl
  549.         setne   al
  550.         or      ah,al
  551.         cmp     ch,[ebx+11]
  552.         mov     [ebx+11],ch
  553.         setne   al
  554.         or      ah,al
  555.         cmp     ebp,[ebx+12]
  556.         mov     [ebx+12],ebp
  557.         setne   al
  558.         or      ah,al
  559.         or      ch,ch
  560.         jz      free_label_symbol_ok
  561.         mov     edx,[address_symbol]
  562.         cmp     edx,[ebx+20]
  563.         mov     [ebx+20],edx
  564.         setne   al
  565.         or      ah,al
  566.       free_label_symbol_ok:
  567.         mov     cx,[current_pass]
  568.         xchg    [ebx+16],cx
  569.         and     byte [ebx+8],not 2
  570.         test    byte [ebx+8],1
  571.         jz      new_free_label
  572.         cmp     cx,[ebx+16]
  573.         je      symbol_already_defined
  574.         inc     cx
  575.         sub     cx,[ebx+16]
  576.         setnz   al
  577.         or      ah,al
  578.         jz      instruction_assembled
  579.         test    byte [ebx+8],8
  580.         jz      instruction_assembled
  581.         mov     cx,[current_pass]
  582.         cmp     cx,[ebx+18]
  583.         jne     instruction_assembled
  584.         or      [next_pass_needed],-1
  585.         jmp     instruction_assembled
  586.       new_free_label:
  587.         or      byte [ebx+8],1
  588.         jmp     instruction_assembled
  589. load_directive:
  590.         lods    byte [esi]
  591.         cmp     al,2
  592.         jne     invalid_argument
  593.         lods    dword [esi]
  594.         cmp     eax,0Fh
  595.         jb      invalid_use_of_symbol
  596.         je      reserved_word_used_as_symbol
  597.         inc     esi
  598.         push    eax
  599.         mov     al,1
  600.         cmp     byte [esi],11h
  601.         jne     load_size_ok
  602.         lods    byte [esi]
  603.         lods    byte [esi]
  604.       load_size_ok:
  605.         cmp     al,8
  606.         ja      invalid_value
  607.         mov     [operand_size],al
  608.         mov     dword [value],0
  609.         mov     dword [value+4],0
  610.         lods    word [esi]
  611.         cmp     ax,82h+'(' shl 8
  612.         jne     invalid_argument
  613.       load_from_code:
  614.         cmp     byte [esi],'.'
  615.         je      invalid_value
  616.         call    get_relative_offset
  617.         neg     eax
  618.         cmp     [next_pass_needed],0
  619.         jne     load_address_ok
  620.         cmp     [value_type],0
  621.         jne     invalid_use_of_symbol
  622.       load_address_ok:
  623.         push    esi edi
  624.         mov     esi,edi
  625.         sub     esi,eax
  626.         jc      bad_load_address
  627.         cmp     esi,[org_start]
  628.         jb      bad_load_address
  629.         mov     edi,value
  630.         movzx   ecx,[operand_size]
  631.         cmp     ecx,eax
  632.         ja      bad_load_address
  633.         rep     movs byte [edi],[esi]
  634.         jmp     value_loaded
  635.       bad_load_address:
  636.         cmp     [error_line],0
  637.         jne     value_loaded
  638.         mov     eax,[current_line]
  639.         mov     [error_line],eax
  640.         mov     [error],value_out_of_range
  641.       value_loaded:
  642.         pop     edi esi
  643.         mov     eax,dword [value]
  644.         mov     edx,dword [value+4]
  645.         pop     ebx
  646.         xor     cx,cx
  647.         jmp     make_constant
  648. store_directive:
  649.         cmp     byte [esi],11h
  650.         je      sized_store
  651.         lods    byte [esi]
  652.         cmp     al,'('
  653.         jne     invalid_argument
  654.         call    get_byte_value
  655.         xor     edx,edx
  656.         movzx   eax,al
  657.         mov     [operand_size],1
  658.         jmp     store_value_ok
  659.       sized_store:
  660.         call    get_value
  661.       store_value_ok:
  662.         cmp     [value_type],0
  663.         jne     invalid_use_of_symbol
  664.         mov     dword [value],eax
  665.         mov     dword [value+4],edx
  666.         lods    word [esi]
  667.         cmp     ax,80h+'(' shl 8
  668.         jne     invalid_argument
  669.         cmp     byte [esi],'.'
  670.         je      invalid_value
  671.         call    get_relative_offset
  672.         neg     eax
  673.         cmp     [next_pass_needed],0
  674.         jne     store_address_ok
  675.         cmp     [value_type],0
  676.         jne     invalid_use_of_symbol
  677.       store_address_ok:
  678.         push    esi edi
  679.         sub     edi,eax
  680.         jc      bad_store_address
  681.         cmp     edi,[org_start]
  682.         jb      bad_store_address
  683.         mov     esi,value
  684.         movzx   ecx,[operand_size]
  685.         cmp     ecx,eax
  686.         ja      bad_store_address
  687.         rep     movs byte [edi],[esi]
  688.         mov     eax,edi
  689.         pop     edi esi
  690.         cmp     edi,[undefined_data_end]
  691.         jne     instruction_assembled
  692.         cmp     eax,[undefined_data_start]
  693.         jbe     instruction_assembled
  694.         mov     [undefined_data_start],eax
  695.         jmp     instruction_assembled
  696.       bad_store_address:
  697.         pop     edi esi
  698.         cmp     [error_line],0
  699.         jne     instruction_assembled
  700.         mov     eax,[current_line]
  701.         mov     [error_line],eax
  702.         mov     [error],value_out_of_range
  703.         jmp     instruction_assembled
  704.  
  705. display_directive:
  706.         lods    byte [esi]
  707.         cmp     al,'('
  708.         jne     invalid_argument
  709.         cmp     byte [esi],0
  710.         jne     display_byte
  711.         inc     esi
  712.         lods    dword [esi]
  713.         mov     ecx,eax
  714.         push    edi
  715.         mov     edi,[display_buffer]
  716.         sub     edi,4
  717.         sub     edi,eax
  718.         mov     [display_buffer],edi
  719.         rep     movs byte [edi],[esi]
  720.         stos    dword [edi]
  721.         pop     edi
  722.         inc     esi
  723.         jmp     display_next
  724.       display_byte:
  725.         call    get_byte_value
  726.         push    edi
  727.         mov     edi,[display_buffer]
  728.         sub     edi,4+1
  729.         mov     [display_buffer],edi
  730.         stos    byte [edi]
  731.         mov     eax,1
  732.         stos    dword [edi]
  733.         pop     edi
  734.       display_next:
  735.         cmp     edi,[display_buffer]
  736.         ja      out_of_memory
  737.         lods    byte [esi]
  738.         cmp     al,','
  739.         je      display_directive
  740.         dec     esi
  741.         jmp     instruction_assembled
  742. flush_display_buffer:
  743.         mov     eax,[display_buffer]
  744.         or      eax,eax
  745.         jz      display_done
  746.         mov     esi,[labels_list]
  747.         cmp     esi,eax
  748.         je      display_done
  749.       display_messages:
  750.         sub     esi,4
  751.         mov     ecx,[esi]
  752.         sub     esi,ecx
  753.         push    esi
  754.         call    display_block
  755.         pop     esi
  756.         cmp     esi,[display_buffer]
  757.         jne     display_messages
  758.         mov     eax,[labels_list]
  759.         mov     [display_buffer],eax
  760.       display_done:
  761.         ret
  762. times_directive:
  763.         lods    byte [esi]
  764.         cmp     al,'('
  765.         jne     invalid_argument
  766.         cmp     byte [esi],'.'
  767.         je      invalid_value
  768.         call    get_dword_value
  769.         cmp     [next_pass_needed],0
  770.         jne     times_value_ok
  771.         cmp     [value_type],0
  772.         jne     invalid_use_of_symbol
  773.       times_value_ok:
  774.         cmp     eax,0
  775.         je      zero_times
  776.         jl      negative_times
  777.         cmp     byte [esi],':'
  778.         jne     times_argument_ok
  779.         inc     esi
  780.       times_argument_ok:
  781.         push    [counter]
  782.         push    [counter_limit]
  783.         mov     [counter_limit],eax
  784.         mov     [counter],1
  785.       times_loop:
  786.         mov     eax,esp
  787.         sub     eax,100h
  788.         jc      stack_overflow
  789.         cmp     eax,[stack_limit]
  790.         jb      stack_overflow
  791.         push    esi
  792.         or      [prefixed_instruction],-1
  793.         call    continue_line
  794.         mov     eax,[counter_limit]
  795.         cmp     [counter],eax
  796.         je      times_done
  797.         inc     [counter]
  798.         pop     esi
  799.         jmp     times_loop
  800.       times_done:
  801.         pop     eax
  802.         pop     [counter_limit]
  803.         pop     [counter]
  804.         jmp     instruction_assembled
  805.       negative_times:
  806.         cmp     [error_line],0
  807.         jne     zero_times
  808.         mov     eax,[current_line]
  809.         mov     [error_line],eax
  810.         mov     [error],invalid_value
  811.       zero_times:
  812.         call    skip_line
  813.         jmp     instruction_assembled
  814.  
  815. virtual_directive:
  816.         lods    byte [esi]
  817.         cmp     al,80h
  818.         jne     virtual_at_current
  819.         lods    byte [esi]
  820.         cmp     al,'('
  821.         jne     invalid_argument
  822.         cmp     byte [esi],'.'
  823.         je      invalid_value
  824.         call    get_address_value
  825.         mov     ebp,[address_symbol]
  826.         xor     ch,ch
  827.         or      bh,bh
  828.         jz      set_virtual
  829.         mov     ch,1
  830.         jmp     set_virtual
  831.       virtual_at_current:
  832.         dec     esi
  833.         mov     al,[labels_type]
  834.         mov     [value_type],al
  835.         mov     ebp,[org_symbol]
  836.         mov     eax,edi
  837.         xor     edx,edx
  838.         sub     eax,dword [org_origin]
  839.         sbb     edx,dword [org_origin+4]
  840.         xor     bx,bx
  841.         xor     cx,cx
  842.       set_virtual:
  843.         push    [org_registers]
  844.         mov     byte [org_registers],bh
  845.         mov     byte [org_registers+1],bl
  846.         mov     byte [org_registers+2],ch
  847.         mov     byte [org_registers+3],cl
  848.         call    allocate_structure_data
  849.         mov     word [ebx],virtual_directive-assembler
  850.         not     eax
  851.         not     edx
  852.         add     eax,1
  853.         adc     edx,0
  854.         add     eax,edi
  855.         adc     edx,0
  856.         xchg    dword [org_origin],eax
  857.         xchg    dword [org_origin+4],edx
  858.         mov     [ebx+10h],eax
  859.         mov     [ebx+14h],edx
  860.         pop     eax
  861.         mov     [ebx+18h],eax
  862.         mov     al,[virtual_data]
  863.         mov     [ebx+2],al
  864.         mov     al,[labels_type]
  865.         mov     [ebx+3],al
  866.         mov     eax,edi
  867.         xchg    eax,[org_start]
  868.         mov     [ebx+0Ch],eax
  869.         xchg    ebp,[org_symbol]
  870.         mov     [ebx+1Ch],ebp
  871.         mov     [ebx+8],edi
  872.         mov     eax,[current_line]
  873.         mov     [ebx+4],eax
  874.         or      [virtual_data],-1
  875.         mov     al,[value_type]
  876.         test    al,1
  877.         jnz     invalid_use_of_symbol
  878.         mov     [labels_type],al
  879.         jmp     instruction_assembled
  880.       allocate_structure_data:
  881.         mov     ebx,[structures_buffer]
  882.         sub     ebx,20h
  883.         cmp     ebx,[free_additional_memory]
  884.         jb      out_of_memory
  885.         mov     [structures_buffer],ebx
  886.         ret
  887.       find_structure_data:
  888.         mov     ebx,[structures_buffer]
  889.       scan_structures:
  890.         cmp     ebx,[additional_memory_end]
  891.         je      no_such_structure
  892.         cmp     ax,[ebx]
  893.         jne     next_structure
  894.         clc
  895.         ret
  896.       next_structure:
  897.         cmp     ax,if_directive-assembler
  898.         je      check_structure_overlapping
  899.         cmp     ax,repeat_directive-assembler
  900.         je      check_structure_overlapping
  901.         cmp     ax,while_directive-assembler
  902.         je      check_structure_overlapping
  903.         add     ebx,20h
  904.         jmp     scan_structures
  905.       check_structure_overlapping:
  906.         cmp     word [ebx],if_directive-assembler
  907.         je      no_such_structure
  908.         cmp     word [ebx],repeat_directive-assembler
  909.         je      no_such_structure
  910.         cmp     word [ebx],while_directive-assembler
  911.         je      no_such_structure
  912.         add     ebx,20h
  913.         jmp     scan_structures
  914.       no_such_structure:
  915.         stc
  916.         ret
  917.       end_virtual:
  918.         call    find_structure_data
  919.         jc      unexpected_instruction
  920.         mov     al,[ebx+2]
  921.         mov     [virtual_data],al
  922.         mov     al,[ebx+3]
  923.         mov     [labels_type],al
  924.         mov     eax,[ebx+10h]
  925.         mov     dword [org_origin],eax
  926.         mov     eax,[ebx+14h]
  927.         mov     dword [org_origin+4],eax
  928.         mov     eax,[ebx+18h]
  929.         mov     [org_registers],eax
  930.         mov     eax,[ebx+0Ch]
  931.         mov     [org_start],eax
  932.         mov     eax,[ebx+1Ch]
  933.         mov     [org_symbol],eax
  934.         mov     edi,[ebx+8]
  935.       remove_structure_data:
  936.         push    esi edi
  937.         mov     esi,[structures_buffer]
  938.         mov     ecx,ebx
  939.         sub     ecx,esi
  940.         lea     edi,[esi+20h]
  941.         mov     [structures_buffer],edi
  942.         shr     ecx,2
  943.         rep     movs dword [edi],[esi]
  944.         pop     edi esi
  945.         ret
  946. repeat_directive:
  947.         cmp     [prefixed_instruction],0
  948.         jne     unexpected_instruction
  949.         lods    byte [esi]
  950.         cmp     al,'('
  951.         jne     invalid_argument
  952.         cmp     byte [esi],'.'
  953.         je      invalid_value
  954.         call    get_dword_value
  955.         cmp     [next_pass_needed],0
  956.         jne     repeat_value_ok
  957.         cmp     [value_type],0
  958.         jne     invalid_use_of_symbol
  959.       repeat_value_ok:
  960.         cmp     eax,0
  961.         je      zero_repeat
  962.         jl      negative_repeat
  963.         call    allocate_structure_data
  964.         mov     word [ebx],repeat_directive-assembler
  965.         xchg    eax,[counter_limit]
  966.         mov     [ebx+10h],eax
  967.         mov     eax,1
  968.         xchg    eax,[counter]
  969.         mov     [ebx+14h],eax
  970.         mov     [ebx+8],esi
  971.         mov     eax,[current_line]
  972.         mov     [ebx+4],eax
  973.         jmp     instruction_assembled
  974.       end_repeat:
  975.         cmp     [prefixed_instruction],0
  976.         jne     unexpected_instruction
  977.         call    find_structure_data
  978.         jc      unexpected_instruction
  979.         mov     eax,[counter_limit]
  980.         inc     [counter]
  981.         cmp     [counter],eax
  982.         jbe     continue_repeating
  983.       stop_repeat:
  984.         mov     eax,[ebx+10h]
  985.         mov     [counter_limit],eax
  986.         mov     eax,[ebx+14h]
  987.         mov     [counter],eax
  988.         call    remove_structure_data
  989.         jmp     instruction_assembled
  990.       continue_repeating:
  991.         mov     esi,[ebx+8]
  992.         jmp     instruction_assembled
  993.       negative_repeat:
  994.         cmp     [error_line],0
  995.         jne     zero_repeat
  996.         mov     eax,[current_line]
  997.         mov     [error_line],eax
  998.         mov     [error],invalid_value
  999.       zero_repeat:
  1000.         mov     al,[esi]
  1001.         or      al,al
  1002.         jz      missing_end_directive
  1003.         cmp     al,0Fh
  1004.         jne     extra_characters_on_line
  1005.         call    find_end_repeat
  1006.         jmp     instruction_assembled
  1007.       find_end_repeat:
  1008.         call    find_structure_end
  1009.         cmp     ax,repeat_directive-assembler
  1010.         jne     unexpected_instruction
  1011.         ret
  1012. while_directive:
  1013.         cmp     [prefixed_instruction],0
  1014.         jne     unexpected_instruction
  1015.         call    allocate_structure_data
  1016.         mov     word [ebx],while_directive-assembler
  1017.         mov     eax,1
  1018.         xchg    eax,[counter]
  1019.         mov     [ebx+10h],eax
  1020.         mov     [ebx+8],esi
  1021.         mov     eax,[current_line]
  1022.         mov     [ebx+4],eax
  1023.       do_while:
  1024.         push    ebx
  1025.         call    calculate_logical_expression
  1026.         or      al,al
  1027.         jnz     while_true
  1028.         mov     al,[esi]
  1029.         or      al,al
  1030.         jz      missing_end_directive
  1031.         cmp     al,0Fh
  1032.         jne     extra_characters_on_line
  1033.       stop_while:
  1034.         call    find_end_while
  1035.         pop     ebx
  1036.         mov     eax,[ebx+10h]
  1037.         mov     [counter],eax
  1038.         call    remove_structure_data
  1039.         jmp     instruction_assembled
  1040.       while_true:
  1041.         pop     ebx
  1042.         jmp     instruction_assembled
  1043.       end_while:
  1044.         cmp     [prefixed_instruction],0
  1045.         jne     unexpected_instruction
  1046.         call    find_structure_data
  1047.         jc      unexpected_instruction
  1048.         mov     eax,[ebx+4]
  1049.         mov     [current_line],eax
  1050.         inc     [counter]
  1051.         jz      too_many_repeats
  1052.         mov     esi,[ebx+8]
  1053.         jmp     do_while
  1054.       find_end_while:
  1055.         call    find_structure_end
  1056.         cmp     ax,while_directive-assembler
  1057.         jne     unexpected_instruction
  1058.         ret
  1059. if_directive:
  1060.         cmp     [prefixed_instruction],0
  1061.         jne     unexpected_instruction
  1062.         call    calculate_logical_expression
  1063.         mov     dl,al
  1064.         mov     al,[esi]
  1065.         or      al,al
  1066.         jz      missing_end_directive
  1067.         cmp     al,0Fh
  1068.         jne     extra_characters_on_line
  1069.         or      dl,dl
  1070.         jnz     if_true
  1071.         call    find_else
  1072.         jc      instruction_assembled
  1073.         mov     al,[esi]
  1074.         cmp     al,1
  1075.         jne     else_true
  1076.         cmp     word [esi+1],if_directive-assembler
  1077.         jne     else_true
  1078.         add     esi,4
  1079.         jmp     if_directive
  1080.       if_true:
  1081.         xor     al,al
  1082.       make_if_structure:
  1083.         call    allocate_structure_data
  1084.         mov     word [ebx],if_directive-assembler
  1085.         mov     byte [ebx+2],al
  1086.         mov     eax,[current_line]
  1087.         mov     [ebx+4],eax
  1088.         jmp     instruction_assembled
  1089.       else_true:
  1090.         or      al,al
  1091.         jz      missing_end_directive
  1092.         cmp     al,0Fh
  1093.         jne     extra_characters_on_line
  1094.         or      al,-1
  1095.         jmp     make_if_structure
  1096.       else_directive:
  1097.         cmp     [prefixed_instruction],0
  1098.         jne     unexpected_instruction
  1099.         mov     ax,if_directive-assembler
  1100.         call    find_structure_data
  1101.         jc      unexpected_instruction
  1102.         cmp     byte [ebx+2],0
  1103.         jne     unexpected_instruction
  1104.       found_else:
  1105.         mov     al,[esi]
  1106.         cmp     al,1
  1107.         jne     skip_else
  1108.         cmp     word [esi+1],if_directive-assembler
  1109.         jne     skip_else
  1110.         add     esi,4
  1111.         call    find_else
  1112.         jnc     found_else
  1113.         call    remove_structure_data
  1114.         jmp     instruction_assembled
  1115.       skip_else:
  1116.         or      al,al
  1117.         jz      missing_end_directive
  1118.         cmp     al,0Fh
  1119.         jne     extra_characters_on_line
  1120.         call    find_end_if
  1121.         call    remove_structure_data
  1122.         jmp     instruction_assembled
  1123.       end_if:
  1124.         cmp     [prefixed_instruction],0
  1125.         jne     unexpected_instruction
  1126.         call    find_structure_data
  1127.         jc      unexpected_instruction
  1128.         call    remove_structure_data
  1129.         jmp     instruction_assembled
  1130.       find_else:
  1131.         call    find_structure_end
  1132.         cmp     ax,else_directive-assembler
  1133.         je      else_found
  1134.         cmp     ax,if_directive-assembler
  1135.         jne     unexpected_instruction
  1136.         stc
  1137.         ret
  1138.       else_found:
  1139.         clc
  1140.         ret
  1141.       find_end_if:
  1142.         call    find_structure_end
  1143.         cmp     ax,if_directive-assembler
  1144.         jne     unexpected_instruction
  1145.         ret
  1146.       find_structure_end:
  1147.         push    [error_line]
  1148.         mov     eax,[current_line]
  1149.         mov     [error_line],eax
  1150.       find_end_directive:
  1151.         call    skip_line
  1152.         lods    byte [esi]
  1153.         cmp     al,0Fh
  1154.         jne     no_end_directive
  1155.         lods    dword [esi]
  1156.         mov     [current_line],eax
  1157.       skip_labels:
  1158.         cmp     byte [esi],2
  1159.         jne     labels_ok
  1160.         add     esi,6
  1161.         jmp     skip_labels
  1162.       labels_ok:
  1163.         cmp     byte [esi],1
  1164.         jne     find_end_directive
  1165.         mov     ax,[esi+1]
  1166.         cmp     ax,prefix_instruction-assembler
  1167.         je      find_end_directive
  1168.         add     esi,4
  1169.         cmp     ax,repeat_directive-assembler
  1170.         je      skip_repeat
  1171.         cmp     ax,while_directive-assembler
  1172.         je      skip_while
  1173.         cmp     ax,if_directive-assembler
  1174.         je      skip_if
  1175.         cmp     ax,else_directive-assembler
  1176.         je      structure_end
  1177.         cmp     ax,end_directive-assembler
  1178.         jne     find_end_directive
  1179.         cmp     byte [esi],1
  1180.         jne     find_end_directive
  1181.         mov     ax,[esi+1]
  1182.         add     esi,4
  1183.         cmp     ax,repeat_directive-assembler
  1184.         je      structure_end
  1185.         cmp     ax,while_directive-assembler
  1186.         je      structure_end
  1187.         cmp     ax,if_directive-assembler
  1188.         jne     find_end_directive
  1189.       structure_end:
  1190.         pop     [error_line]
  1191.         ret
  1192.       no_end_directive:
  1193.         mov     eax,[error_line]
  1194.         mov     [current_line],eax
  1195.         jmp     missing_end_directive
  1196.       skip_repeat:
  1197.         call    find_end_repeat
  1198.         jmp     find_end_directive
  1199.       skip_while:
  1200.         call    find_end_while
  1201.         jmp     find_end_directive
  1202.       skip_if:
  1203.         call    skip_if_block
  1204.         jmp     find_end_directive
  1205.       skip_if_block:
  1206.         call    find_else
  1207.         jc      if_block_skipped
  1208.         cmp     byte [esi],1
  1209.         jne     skip_after_else
  1210.         cmp     word [esi+1],if_directive-assembler
  1211.         jne     skip_after_else
  1212.         add     esi,4
  1213.         jmp     skip_if_block
  1214.       skip_after_else:
  1215.         call    find_end_if
  1216.       if_block_skipped:
  1217.         ret
  1218. end_directive:
  1219.         lods    byte [esi]
  1220.         cmp     al,1
  1221.         jne     invalid_argument
  1222.         lods    word [esi]
  1223.         inc     esi
  1224.         cmp     ax,virtual_directive-assembler
  1225.         je      end_virtual
  1226.         cmp     ax,repeat_directive-assembler
  1227.         je      end_repeat
  1228.         cmp     ax,while_directive-assembler
  1229.         je      end_while
  1230.         cmp     ax,if_directive-assembler
  1231.         je      end_if
  1232.         cmp     ax,data_directive-assembler
  1233.         je      end_data
  1234.         jmp     invalid_argument
  1235. break_directive:
  1236.         mov     ebx,[structures_buffer]
  1237.         mov     al,[esi]
  1238.         or      al,al
  1239.         jz      find_breakable_structure
  1240.         cmp     al,0Fh
  1241.         jne     extra_characters_on_line
  1242.       find_breakable_structure:
  1243.         cmp     ebx,[additional_memory_end]
  1244.         je      unexpected_instruction
  1245.         mov     ax,[ebx]
  1246.         cmp     ax,repeat_directive-assembler
  1247.         je      break_repeat
  1248.         cmp     ax,while_directive-assembler
  1249.         je      break_while
  1250.         cmp     ax,if_directive-assembler
  1251.         je      break_if
  1252.         add     ebx,20h
  1253.         jmp     find_breakable_structure
  1254.       break_if:
  1255.         push    [current_line]
  1256.         mov     eax,[ebx+4]
  1257.         mov     [current_line],eax
  1258.         call    remove_structure_data
  1259.         call    skip_if_block
  1260.         pop     [current_line]
  1261.         mov     ebx,[structures_buffer]
  1262.         jmp     find_breakable_structure
  1263.       break_repeat:
  1264.         push    ebx
  1265.         call    find_end_repeat
  1266.         pop     ebx
  1267.         jmp     stop_repeat
  1268.       break_while:
  1269.         push    ebx
  1270.         jmp     stop_while
  1271.  
  1272. data_bytes:
  1273.         call    define_data
  1274.         lods    byte [esi]
  1275.         cmp     al,'('
  1276.         je      get_byte
  1277.         cmp     al,'?'
  1278.         jne     invalid_argument
  1279.         mov     eax,edi
  1280.         mov     byte [edi],0
  1281.         inc     edi
  1282.         jmp     undefined_data
  1283.       get_byte:
  1284.         cmp     byte [esi],0
  1285.         je      get_string
  1286.         call    get_byte_value
  1287.         stos    byte [edi]
  1288.         ret
  1289.       get_string:
  1290.         inc     esi
  1291.         lods    dword [esi]
  1292.         mov     ecx,eax
  1293.         lea     eax,[edi+ecx]
  1294.         cmp     eax,[display_buffer]
  1295.         ja      out_of_memory
  1296.         rep     movs byte [edi],[esi]
  1297.         inc     esi
  1298.         ret
  1299.       undefined_data:
  1300.         cmp     [virtual_data],0
  1301.         je      mark_undefined_data
  1302.         ret
  1303.       mark_undefined_data:
  1304.         cmp     eax,[undefined_data_end]
  1305.         je      undefined_data_ok
  1306.         mov     [undefined_data_start],eax
  1307.       undefined_data_ok:
  1308.         mov     [undefined_data_end],edi
  1309.         ret
  1310.       define_data:
  1311.         cmp     edi,[display_buffer]
  1312.         jae     out_of_memory
  1313.         cmp     byte [esi],'('
  1314.         jne     simple_data_value
  1315.         mov     ebx,esi
  1316.         inc     esi
  1317.         call    skip_expression
  1318.         xchg    esi,ebx
  1319.         cmp     byte [ebx],81h
  1320.         jne     simple_data_value
  1321.         inc     esi
  1322.         call    get_dword_value
  1323.         cmp     [next_pass_needed],0
  1324.         jne     dup_value_ok
  1325.         cmp     [value_type],0
  1326.         jne     invalid_use_of_symbol
  1327.       dup_value_ok:
  1328.         inc     esi
  1329.         cmp     eax,0
  1330.         jg      dup_positive
  1331.         cmp     [error_line],0
  1332.         jne     dup_invalid
  1333.         mov     eax,[current_line]
  1334.         mov     [error_line],eax
  1335.         mov     [error],invalid_value
  1336.       dup_invalid:
  1337.         mov     eax,1
  1338.       dup_positive:
  1339.         cmp     byte [esi],'{'
  1340.         jne     duplicate_single_data_value
  1341.         inc     esi
  1342.       duplicate_data:
  1343.         push    eax esi
  1344.       duplicated_values:
  1345.         cmp     edi,[display_buffer]
  1346.         jae     out_of_memory
  1347.         call    near dword [esp+8]
  1348.         lods    byte [esi]
  1349.         cmp     al,','
  1350.         je      duplicated_values
  1351.         cmp     al,'}'
  1352.         jne     invalid_argument
  1353.         pop     ebx eax
  1354.         dec     eax
  1355.         jz      data_defined
  1356.         mov     esi,ebx
  1357.         jmp     duplicate_data
  1358.       duplicate_single_data_value:
  1359.         cmp     edi,[display_buffer]
  1360.         jae     out_of_memory
  1361.         push    eax esi
  1362.         call    near dword [esp+8]
  1363.         pop     ebx eax
  1364.         dec     eax
  1365.         jz      data_defined
  1366.         mov     esi,ebx
  1367.         jmp     duplicate_single_data_value
  1368.       simple_data_value:
  1369.         cmp     edi,[display_buffer]
  1370.         jae     out_of_memory
  1371.         call    near dword [esp]
  1372.       data_defined:
  1373.         lods    byte [esi]
  1374.         cmp     al,','
  1375.         je      define_data
  1376.         dec     esi
  1377.         add     esp,4
  1378.         jmp     instruction_assembled
  1379. data_unicode:
  1380.         or      [base_code],-1
  1381.         jmp     define_words
  1382. data_words:
  1383.         mov     [base_code],0
  1384.       define_words:
  1385.         call    define_data
  1386.         lods    byte [esi]
  1387.         cmp     al,'('
  1388.         je      get_word
  1389.         cmp     al,'?'
  1390.         jne     invalid_argument
  1391.         mov     eax,edi
  1392.         mov     word [edi],0
  1393.         scas    word [edi]
  1394.         jmp     undefined_data
  1395.         ret
  1396.       get_word:
  1397.         cmp     [base_code],0
  1398.         je      word_data_value
  1399.         cmp     byte [esi],0
  1400.         je      word_string
  1401.       word_data_value:
  1402.         call    get_word_value
  1403.         call    mark_relocation
  1404.         stos    word [edi]
  1405.         ret
  1406.       word_string:
  1407.         inc     esi
  1408.         lods    dword [esi]
  1409.         mov     ecx,eax
  1410.         jecxz   word_string_ok
  1411.         lea     eax,[edi+ecx*2]
  1412.         cmp     eax,[display_buffer]
  1413.         ja      out_of_memory
  1414.         xor     ah,ah
  1415.       copy_word_string:
  1416.         lods    byte [esi]
  1417.         stos    word [edi]
  1418.         loop    copy_word_string
  1419.       word_string_ok:
  1420.         inc     esi
  1421.         ret
  1422. data_dwords:
  1423.         call    define_data
  1424.         lods    byte [esi]
  1425.         cmp     al,'('
  1426.         je      get_dword
  1427.         cmp     al,'?'
  1428.         jne     invalid_argument
  1429.         mov     eax,edi
  1430.         mov     dword [edi],0
  1431.         scas    dword [edi]
  1432.         jmp     undefined_data
  1433.       get_dword:
  1434.         push    esi
  1435.         call    get_dword_value
  1436.         pop     ebx
  1437.         cmp     byte [esi],':'
  1438.         je      complex_dword
  1439.         call    mark_relocation
  1440.         stos    dword [edi]
  1441.         ret
  1442.       complex_dword:
  1443.         mov     esi,ebx
  1444.         cmp     byte [esi],'.'
  1445.         je      invalid_value
  1446.         call    get_word_value
  1447.         push    eax
  1448.         inc     esi
  1449.         lods    byte [esi]
  1450.         cmp     al,'('
  1451.         jne     invalid_operand
  1452.         mov     al,[value_type]
  1453.         push    eax
  1454.         cmp     byte [esi],'.'
  1455.         je      invalid_value
  1456.         call    get_word_value
  1457.         call    mark_relocation
  1458.         stos    word [edi]
  1459.         pop     eax
  1460.         mov     [value_type],al
  1461.         pop     eax
  1462.         call    mark_relocation
  1463.         stos    word [edi]
  1464.         ret
  1465. data_pwords:
  1466.         call    define_data
  1467.         lods    byte [esi]
  1468.         cmp     al,'('
  1469.         je      get_pword
  1470.         cmp     al,'?'
  1471.         jne     invalid_argument
  1472.         mov     eax,edi
  1473.         mov     dword [edi],0
  1474.         scas    dword [edi]
  1475.         mov     word [edi],0
  1476.         scas    word [edi]
  1477.         jmp     undefined_data
  1478.       get_pword:
  1479.         push    esi
  1480.         call    get_pword_value
  1481.         pop     ebx
  1482.         cmp     byte [esi],':'
  1483.         je      complex_pword
  1484.         call    mark_relocation
  1485.         stos    dword [edi]
  1486.         mov     ax,dx
  1487.         stos    word [edi]
  1488.         ret
  1489.       complex_pword:
  1490.         mov     esi,ebx
  1491.         cmp     byte [esi],'.'
  1492.         je      invalid_value
  1493.         call    get_word_value
  1494.         push    eax
  1495.         inc     esi
  1496.         lods    byte [esi]
  1497.         cmp     al,'('
  1498.         jne     invalid_operand
  1499.         mov     al,[value_type]
  1500.         push    eax
  1501.         cmp     byte [esi],'.'
  1502.         je      invalid_value
  1503.         call    get_dword_value
  1504.         call    mark_relocation
  1505.         stos    dword [edi]
  1506.         pop     eax
  1507.         mov     [value_type],al
  1508.         pop     eax
  1509.         call    mark_relocation
  1510.         stos    word [edi]
  1511.         ret
  1512. data_qwords:
  1513.         call    define_data
  1514.         lods    byte [esi]
  1515.         cmp     al,'('
  1516.         je      get_qword
  1517.         cmp     al,'?'
  1518.         jne     invalid_argument
  1519.         mov     eax,edi
  1520.         mov     dword [edi],0
  1521.         scas    dword [edi]
  1522.         mov     dword [edi],0
  1523.         scas    dword [edi]
  1524.         jmp     undefined_data
  1525.       get_qword:
  1526.         call    get_qword_value
  1527.         call    mark_relocation
  1528.         stos    dword [edi]
  1529.         mov     eax,edx
  1530.         stos    dword [edi]
  1531.         ret
  1532. data_twords:
  1533.         call    define_data
  1534.         lods    byte [esi]
  1535.         cmp     al,'('
  1536.         je      get_tword
  1537.         cmp     al,'?'
  1538.         jne     invalid_argument
  1539.         mov     eax,edi
  1540.         mov     dword [edi],0
  1541.         scas    dword [edi]
  1542.         mov     dword [edi],0
  1543.         scas    dword [edi]
  1544.         mov     word [edi],0
  1545.         scas    word [edi]
  1546.         jmp     undefined_data
  1547.       get_tword:
  1548.         cmp     byte [esi],'.'
  1549.         jne     complex_tword
  1550.         inc     esi
  1551.         cmp     word [esi+8],8000h
  1552.         je      fp_zero_tword
  1553.         mov     eax,[esi]
  1554.         stos    dword [edi]
  1555.         mov     eax,[esi+4]
  1556.         stos    dword [edi]
  1557.         mov     ax,[esi+8]
  1558.         add     ax,3FFFh
  1559.         cmp     ax,8000h
  1560.         jae     value_out_of_range
  1561.         mov     bl,[esi+11]
  1562.         shl     bx,15
  1563.         or      ax,bx
  1564.         stos    word [edi]
  1565.         add     esi,13
  1566.         ret
  1567.       fp_zero_tword:
  1568.         xor     eax,eax
  1569.         stos    dword [edi]
  1570.         stos    dword [edi]
  1571.         mov     al,[esi+11]
  1572.         shl     ax,15
  1573.         stos    word [edi]
  1574.         add     esi,13
  1575.         ret
  1576.       complex_tword:
  1577.         call    get_word_value
  1578.         push    eax
  1579.         inc     esi
  1580.         lods    byte [esi]
  1581.         cmp     al,'('
  1582.         jne     invalid_operand
  1583.         mov     al,[value_type]
  1584.         push    eax
  1585.         cmp     byte [esi],'.'
  1586.         je      invalid_value
  1587.         call    get_qword_value
  1588.         call    mark_relocation
  1589.         stos    dword [edi]
  1590.         mov     eax,edx
  1591.         stos    dword [edi]
  1592.         pop     eax
  1593.         mov     [value_type],al
  1594.         pop     eax
  1595.         call    mark_relocation
  1596.         stos    word [edi]
  1597.         ret
  1598. data_file:
  1599.         lods    word [esi]
  1600.         cmp     ax,'('
  1601.         jne     invalid_argument
  1602.         add     esi,4
  1603.         call    open_binary_file
  1604.         mov     eax,[esi-4]
  1605.         lea     esi,[esi+eax+1]
  1606.         mov     al,2
  1607.         xor     edx,edx
  1608.         call    lseek
  1609.         push    eax
  1610.         xor     edx,edx
  1611.         cmp     byte [esi],':'
  1612.         jne     position_ok
  1613.         inc     esi
  1614.         cmp     byte [esi],'('
  1615.         jne     invalid_argument
  1616.         inc     esi
  1617.         cmp     byte [esi],'.'
  1618.         je      invalid_value
  1619.         push    ebx
  1620.         call    get_dword_value
  1621.         pop     ebx
  1622.         mov     edx,eax
  1623.         sub     [esp],edx
  1624.       position_ok:
  1625.         cmp     byte [esi],','
  1626.         jne     size_ok
  1627.         inc     esi
  1628.         cmp     byte [esi],'('
  1629.         jne     invalid_argument
  1630.         inc     esi
  1631.         cmp     byte [esi],'.'
  1632.         je      invalid_value
  1633.         push    ebx edx
  1634.         call    get_dword_value
  1635.         pop     edx ebx
  1636.         mov     [esp],eax
  1637.       size_ok:
  1638.         xor     al,al
  1639.         call    lseek
  1640.         pop     ecx
  1641.         mov     edx,edi
  1642.         add     edi,ecx
  1643.         jc      out_of_memory
  1644.         cmp     edi,[display_buffer]
  1645.         ja      out_of_memory
  1646.         call    read
  1647.         jc      error_reading_file
  1648.         call    close
  1649.         lods    byte [esi]
  1650.         cmp     al,','
  1651.         je      data_file
  1652.         dec     esi
  1653.         jmp     instruction_assembled
  1654.       open_binary_file:
  1655.         push    esi
  1656.         push    edi
  1657.         mov     esi,[current_line]
  1658.         mov     esi,[esi]
  1659.       get_current_path:
  1660.         lodsb
  1661.         stosb
  1662.         or      al,al
  1663.         jnz     get_current_path
  1664.       cut_current_path:
  1665.         cmp     edi,[esp]
  1666.         je      current_path_ok
  1667.         cmp     byte [edi-1],'\'
  1668.         je      current_path_ok
  1669.         cmp     byte [edi-1],'/'
  1670.         je      current_path_ok
  1671.         dec     edi
  1672.         jmp     cut_current_path
  1673.       current_path_ok:
  1674.         mov     esi,[esp+4]
  1675.         call    preprocess_path
  1676.         pop     edx
  1677.         mov     esi,edx
  1678.         call    open
  1679.         jnc     file_opened
  1680.         mov     edi,esi
  1681.         mov     esi,[esp]
  1682.         push    edi
  1683.         call    preprocess_path
  1684.         pop     edx
  1685.         mov     esi,edx
  1686.         call    open
  1687.         jc      file_not_found
  1688.       file_opened:
  1689.         mov     edi,esi
  1690.         pop     esi
  1691.         ret
  1692. reserve_bytes:
  1693.         lods    byte [esi]
  1694.         cmp     al,'('
  1695.         jne     invalid_argument
  1696.         cmp     byte [esi],'.'
  1697.         je      invalid_value
  1698.         call    get_dword_value
  1699.         cmp     [next_pass_needed],0
  1700.         jne     rb_value_ok
  1701.         cmp     [value_type],0
  1702.         jne     invalid_use_of_symbol
  1703.       rb_value_ok:
  1704.         cmp     eax,0
  1705.         jl      reserve_negative
  1706.         mov     ecx,eax
  1707.         mov     edx,ecx
  1708.         add     edx,edi
  1709.         jc      out_of_memory
  1710.         cmp     edx,[display_buffer]
  1711.         ja      out_of_memory
  1712.         push    edi
  1713.         cmp     [next_pass_needed],0
  1714.         je      zero_bytes
  1715.         add     edi,ecx
  1716.         jmp     reserved_data
  1717.       zero_bytes:
  1718.         xor     eax,eax
  1719.         shr     ecx,1
  1720.         jnc     bytes_stosb_ok
  1721.         stos    byte [edi]
  1722.       bytes_stosb_ok:
  1723.         shr     ecx,1
  1724.         jnc     bytes_stosw_ok
  1725.         stos    word [edi]
  1726.       bytes_stosw_ok:
  1727.         rep     stos dword [edi]
  1728.       reserved_data:
  1729.         pop     eax
  1730.         call    undefined_data
  1731.         jmp     instruction_assembled
  1732.       reserve_negative:
  1733.         cmp     [error_line],0
  1734.         jne     instruction_assembled
  1735.         mov     eax,[current_line]
  1736.         mov     [error_line],eax
  1737.         mov     [error],invalid_value
  1738.         jmp     instruction_assembled
  1739. reserve_words:
  1740.         lods    byte [esi]
  1741.         cmp     al,'('
  1742.         jne     invalid_argument
  1743.         cmp     byte [esi],'.'
  1744.         je      invalid_value
  1745.         call    get_dword_value
  1746.         cmp     [next_pass_needed],0
  1747.         jne     rw_value_ok
  1748.         cmp     [value_type],0
  1749.         jne     invalid_use_of_symbol
  1750.       rw_value_ok:
  1751.         cmp     eax,0
  1752.         jl      reserve_negative
  1753.         mov     ecx,eax
  1754.         mov     edx,ecx
  1755.         shl     edx,1
  1756.         jc      out_of_memory
  1757.         add     edx,edi
  1758.         jc      out_of_memory
  1759.         cmp     edx,[display_buffer]
  1760.         ja      out_of_memory
  1761.         push    edi
  1762.         cmp     [next_pass_needed],0
  1763.         je      zero_words
  1764.         lea     edi,[edi+ecx*2]
  1765.         jmp     reserved_data
  1766.       zero_words:
  1767.         xor     eax,eax
  1768.         shr     ecx,1
  1769.         jnc     words_stosw_ok
  1770.         stos    word [edi]
  1771.       words_stosw_ok:
  1772.         rep     stos dword [edi]
  1773.         jmp     reserved_data
  1774. reserve_dwords:
  1775.         lods    byte [esi]
  1776.         cmp     al,'('
  1777.         jne     invalid_argument
  1778.         cmp     byte [esi],'.'
  1779.         je      invalid_value
  1780.         call    get_dword_value
  1781.         cmp     [next_pass_needed],0
  1782.         jne     rd_value_ok
  1783.         cmp     [value_type],0
  1784.         jne     invalid_use_of_symbol
  1785.       rd_value_ok:
  1786.         cmp     eax,0
  1787.         jl      reserve_negative
  1788.         mov     ecx,eax
  1789.         mov     edx,ecx
  1790.         shl     edx,1
  1791.         jc      out_of_memory
  1792.         shl     edx,1
  1793.         jc      out_of_memory
  1794.         add     edx,edi
  1795.         jc      out_of_memory
  1796.         cmp     edx,[display_buffer]
  1797.         ja      out_of_memory
  1798.         push    edi
  1799.         cmp     [next_pass_needed],0
  1800.         je      zero_dwords
  1801.         lea     edi,[edi+ecx*4]
  1802.         jmp     reserved_data
  1803.       zero_dwords:
  1804.         xor     eax,eax
  1805.         rep     stos dword [edi]
  1806.         jmp     reserved_data
  1807. reserve_pwords:
  1808.         lods    byte [esi]
  1809.         cmp     al,'('
  1810.         jne     invalid_argument
  1811.         cmp     byte [esi],'.'
  1812.         je      invalid_value
  1813.         call    get_dword_value
  1814.         cmp     [next_pass_needed],0
  1815.         jne     rp_value_ok
  1816.         cmp     [value_type],0
  1817.         jne     invalid_use_of_symbol
  1818.       rp_value_ok:
  1819.         cmp     eax,0
  1820.         jl      reserve_negative
  1821.         mov     ecx,eax
  1822.         shl     ecx,1
  1823.         jc      out_of_memory
  1824.         add     ecx,eax
  1825.         mov     edx,ecx
  1826.         shl     edx,1
  1827.         jc      out_of_memory
  1828.         add     edx,edi
  1829.         jc      out_of_memory
  1830.         cmp     edx,[display_buffer]
  1831.         ja      out_of_memory
  1832.         push    edi
  1833.         cmp     [next_pass_needed],0
  1834.         je      zero_words
  1835.         lea     edi,[edi+ecx*2]
  1836.         jmp     reserved_data
  1837. reserve_qwords:
  1838.         lods    byte [esi]
  1839.         cmp     al,'('
  1840.         jne     invalid_argument
  1841.         cmp     byte [esi],'.'
  1842.         je      invalid_value
  1843.         call    get_dword_value
  1844.         cmp     [next_pass_needed],0
  1845.         jne     rq_value_ok
  1846.         cmp     [value_type],0
  1847.         jne     invalid_use_of_symbol
  1848.       rq_value_ok:
  1849.         cmp     eax,0
  1850.         jl      reserve_negative
  1851.         mov     ecx,eax
  1852.         shl     ecx,1
  1853.         jc      out_of_memory
  1854.         mov     edx,ecx
  1855.         shl     edx,1
  1856.         jc      out_of_memory
  1857.         shl     edx,1
  1858.         jc      out_of_memory
  1859.         add     edx,edi
  1860.         jc      out_of_memory
  1861.         cmp     edx,[display_buffer]
  1862.         ja      out_of_memory
  1863.         push    edi
  1864.         cmp     [next_pass_needed],0
  1865.         je      zero_dwords
  1866.         lea     edi,[edi+ecx*4]
  1867.         jmp     reserved_data
  1868. reserve_twords:
  1869.         lods    byte [esi]
  1870.         cmp     al,'('
  1871.         jne     invalid_argument
  1872.         cmp     byte [esi],'.'
  1873.         je      invalid_value
  1874.         call    get_dword_value
  1875.         cmp     [next_pass_needed],0
  1876.         jne     rt_value_ok
  1877.         cmp     [value_type],0
  1878.         jne     invalid_use_of_symbol
  1879.       rt_value_ok:
  1880.         cmp     eax,0
  1881.         jl      reserve_negative
  1882.         mov     ecx,eax
  1883.         shl     ecx,2
  1884.         jc      out_of_memory
  1885.         add     ecx,eax
  1886.         mov     edx,ecx
  1887.         shl     edx,1
  1888.         jc      out_of_memory
  1889.         add     edx,edi
  1890.         jc      out_of_memory
  1891.         cmp     edx,[display_buffer]
  1892.         ja      out_of_memory
  1893.         push    edi
  1894.         cmp     [next_pass_needed],0
  1895.         je      zero_words
  1896.         lea     edi,[edi+ecx*2]
  1897.         jmp     reserved_data
  1898. align_directive:
  1899.         lods    byte [esi]
  1900.         cmp     al,'('
  1901.         jne     invalid_argument
  1902.         cmp     byte [esi],'.'
  1903.         je      invalid_value
  1904.         call    get_dword_value
  1905.         cmp     [value_type],0
  1906.         jne     invalid_use_of_symbol
  1907.         mov     edx,eax
  1908.         dec     edx
  1909.         test    eax,edx
  1910.         jnz     invalid_value
  1911.         or      eax,eax
  1912.         jz      invalid_value
  1913.         cmp     eax,1
  1914.         je      instruction_assembled
  1915.         mov     ecx,edi
  1916.         sub     ecx,dword [org_origin]
  1917.         cmp     [org_registers],0
  1918.         jne     section_not_aligned_enough
  1919.         cmp     [labels_type],0
  1920.         je      make_alignment
  1921.         cmp     [output_format],3
  1922.         je      pe_alignment
  1923.         mov     ebx,[org_symbol]
  1924.         cmp     byte [ebx],0
  1925.         jne     section_not_aligned_enough
  1926.         cmp     eax,[ebx+10h]
  1927.         jbe     make_alignment
  1928.         jmp     section_not_aligned_enough
  1929.       pe_alignment:
  1930.         cmp     eax,1000h
  1931.         ja      section_not_aligned_enough
  1932.       make_alignment:
  1933.         dec     eax
  1934.         and     ecx,eax
  1935.         jz      instruction_assembled
  1936.         neg     ecx
  1937.         add     ecx,eax
  1938.         inc     ecx
  1939.         mov     edx,ecx
  1940.         add     edx,edi
  1941.         jc      out_of_memory
  1942.         cmp     edx,[display_buffer]
  1943.         ja      out_of_memory
  1944.         push    edi
  1945.         cmp     [next_pass_needed],0
  1946.         je      nops
  1947.         add     edi,ecx
  1948.         jmp     reserved_data
  1949.       nops:
  1950.         mov     eax,90909090h
  1951.         shr     ecx,1
  1952.         jnc     nops_stosb_ok
  1953.         stos    byte [edi]
  1954.       nops_stosb_ok:
  1955.         shr     ecx,1
  1956.         jnc     nops_stosw_ok
  1957.         stos    word [edi]
  1958.       nops_stosw_ok:
  1959.         rep     stos dword [edi]
  1960.         jmp     reserved_data
  1961.