Subversion Repositories Kolibri OS

Rev

Rev 1044 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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