Subversion Repositories Kolibri OS

Rev

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

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