Subversion Repositories Kolibri OS

Rev

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

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