Subversion Repositories Kolibri OS

Rev

Rev 242 | Blame | Last modification | View Log | Download | RSS feed

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