Subversion Repositories Kolibri OS

Rev

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

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