Subversion Repositories Kolibri OS

Rev

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

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