Subversion Repositories Kolibri OS

Rev

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

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