Subversion Repositories Kolibri OS

Rev

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

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