Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. ; flat assembler core
  3. ; Copyright (c) 1999-2005, Tomasz Grysztar.
  4. ; All rights reserved.
  5.  
  6. formatter:
  7.         cmp     [output_file],0
  8.         jne     output_path_ok
  9.         push    edi
  10.         mov     esi,[input_file]
  11.         mov     edi,[free_additional_memory]
  12.       copy_output_path:
  13.         lods    byte [esi]
  14.         cmp     edi,[structures_buffer]
  15.         jae     out_of_memory
  16.         stos    byte [edi]
  17.         or      al,al
  18.         jnz     copy_output_path
  19.         dec     edi
  20.         mov     eax,edi
  21.       find_extension:
  22.         dec     eax
  23.         cmp     eax,[free_additional_memory]
  24.         jb      extension_found
  25.         cmp     byte [eax],'\'
  26.         je      extension_found
  27.         cmp     byte [eax],'/'
  28.         je      extension_found
  29.         cmp     byte [eax],'.'
  30.         jne     find_extension
  31.         mov     edi,eax
  32.       extension_found:
  33.         lea     eax,[edi+9]
  34.         cmp     eax,[structures_buffer]
  35.         jae     out_of_memory
  36.         cmp     [output_format],2
  37.         je      exe_extension
  38.         jb      bin_extension
  39.         cmp     [output_format],4
  40.         je      obj_extension
  41.         cmp     [output_format],5
  42.         je      o_extension
  43.         cmp     [output_format],3
  44.         jne     no_extension
  45.         cmp     [subsystem],1
  46.         je      sys_extension
  47.         bt      [format_flags],8
  48.         jnc     exe_extension
  49.         mov     eax,'.dll'
  50.         jmp     make_extension
  51.       sys_extension:
  52.         mov     eax,'.sys'
  53.         jmp     make_extension
  54.       bin_extension:
  55.         mov     eax,'.bin'
  56.         bt      [format_flags],0
  57.         jnc     make_extension
  58.         mov     eax,'.com'
  59.         jmp     make_extension
  60.       obj_extension:
  61.         mov     eax,'.obj'
  62.         jmp     make_extension
  63.       o_extension:
  64.         mov     eax,'.o'
  65.         bt      [format_flags],0
  66.         jnc     make_extension
  67.       no_extension:
  68.         xor     eax,eax
  69.         jmp     make_extension
  70.       exe_extension:
  71.         mov     eax,'.exe'
  72.       make_extension:
  73.         xchg    eax,[edi]
  74.         scas    dword [edi]
  75.         mov     byte [edi],0
  76.         scas    byte [edi]
  77.         mov     esi,edi
  78.         stos    dword [edi]
  79.         sub     edi,9
  80.         xor     eax,eax
  81.         mov     ebx,characters
  82.       adapt_case:
  83.         mov     al,[esi]
  84.         or      al,al
  85.         jz      adapt_next
  86.         xlat    byte [ebx]
  87.         cmp     al,[esi]
  88.         je      adapt_ok
  89.         sub     byte [edi],20h
  90.       adapt_ok:
  91.         inc     esi
  92.       adapt_next:
  93.         inc     edi
  94.         cmp     byte [edi],0
  95.         jne     adapt_case
  96.         mov     esi,edi
  97.         lea     ecx,[esi+1]
  98.         sub     ecx,[free_additional_memory]
  99.         mov     edi,[structures_buffer]
  100.         dec     edi
  101.         std
  102.         rep     movs byte [edi],[esi]
  103.         cld
  104.         inc     edi
  105.         mov     [structures_buffer],edi
  106.         mov     [output_file],edi
  107.         pop     edi
  108.       output_path_ok:
  109.         cmp     [output_format],4
  110.         je      coff_formatter
  111.         cmp     [output_format],5
  112.         jne     common_formatter
  113.         bt      [format_flags],0
  114.         jnc     elf_formatter
  115.       common_formatter:
  116.         mov     eax,edi
  117.         sub     eax,[code_start]
  118.         mov     [real_code_size],eax
  119.         cmp     edi,[undefined_data_end]
  120.         jne     calculate_code_size
  121.         mov     edi,[undefined_data_start]
  122.       calculate_code_size:
  123.         sub     edi,[code_start]
  124.         mov     [code_size],edi
  125.         mov     [written_size],0
  126.         mov     edx,[output_file]
  127.         call    create
  128.         jc      write_failed
  129.         cmp     [output_format],3
  130.         jne     stub_written
  131.         mov     edx,[code_start]
  132.         mov     ecx,[stub_size]
  133.         sub     edx,ecx
  134.         add     [written_size],ecx
  135.         call    write
  136.       stub_written:
  137.         cmp     [output_format],2
  138.         jne     write_output
  139.         call    write_mz_header
  140.       write_output:
  141.         call    write_code
  142.       output_written:
  143.         call    close
  144.         ret
  145.       write_code:
  146.         mov     eax,[written_size]
  147.         mov     [headers_size],eax
  148.         mov     edx,[code_start]
  149.         mov     ecx,[code_size]
  150.         add     [written_size],ecx
  151.         call    write
  152.         jc      write_failed
  153.         ret
  154. format_directive:
  155.         cmp     edi,[code_start]
  156.         jne     unexpected_instruction
  157.         cmp     [virtual_data],0
  158.         jne     unexpected_instruction
  159.         cmp     [output_format],0
  160.         jne     unexpected_instruction
  161.         lods    byte [esi]
  162.         cmp     al,17h
  163.         je      format_prefix
  164.         cmp     al,18h
  165.         jne     invalid_argument
  166.         lods    byte [esi]
  167.       select_format:
  168.         mov     dl,al
  169.         shr     al,4
  170.         mov     [output_format],al
  171.         and     edx,0Fh
  172.         or      [format_flags],edx
  173.         cmp     al,2
  174.         je      format_mz
  175.         cmp     al,3
  176.         je      format_pe
  177.         cmp     al,4
  178.         je      format_coff
  179.         cmp     al,5
  180.         je      format_elf
  181.         jmp     instruction_assembled
  182.       format_prefix:
  183.         lods    byte [esi]
  184.         mov     ah,al
  185.         lods    byte [esi]
  186.         cmp     al,18h
  187.         jne     invalid_argument
  188.         lods    byte [esi]
  189.         mov     edx,eax
  190.         shr     dl,4
  191.         shr     dh,4
  192.         cmp     dl,dh
  193.         jne     invalid_argument
  194.         or      al,ah
  195.         jmp     select_format
  196. entry_directive:
  197.         bts     [format_flags],10h
  198.         jc      setting_already_specified
  199.         mov     al,[output_format]
  200.         cmp     al,2
  201.         je      mz_entry
  202.         cmp     al,3
  203.         je      pe_entry
  204.         cmp     al,5
  205.         jne     illegal_instruction
  206.         bt      [format_flags],0
  207.         jc      elf_entry
  208.         jmp     illegal_instruction
  209. stack_directive:
  210.         bts     [format_flags],11h
  211.         jc      setting_already_specified
  212.         mov     al,[output_format]
  213.         cmp     al,2
  214.         je      mz_stack
  215.         cmp     al,3
  216.         je      pe_stack
  217.         jmp     illegal_instruction
  218. heap_directive:
  219.         bts     [format_flags],12h
  220.         jc      setting_already_specified
  221.         mov     al,[output_format]
  222.         cmp     al,2
  223.         je      mz_heap
  224.         cmp     al,3
  225.         je      pe_heap
  226.         jmp     illegal_instruction
  227. section_directive:
  228.         cmp     [virtual_data],0
  229.         jne     illegal_instruction
  230.         mov     al,[output_format]
  231.         cmp     al,3
  232.         je      pe_section
  233.         cmp     al,4
  234.         je      coff_section
  235.         cmp     al,5
  236.         je      elf_section
  237.         jmp     illegal_instruction
  238. public_directive:
  239.         mov     al,[output_format]
  240.         cmp     al,4
  241.         je      public_allowed
  242.         cmp     al,5
  243.         jne     illegal_instruction
  244.         bt      [format_flags],0
  245.         jc      illegal_instruction
  246.       public_allowed:
  247.         lods    byte [esi]
  248.         cmp     al,2
  249.         jne     invalid_argument
  250.         lods    dword [esi]
  251.         cmp     eax,0Fh
  252.         jb      invalid_use_of_symbol
  253.         je      reserved_word_used_as_symbol
  254.         mov     dx,[current_pass]
  255.         mov     [eax+18],dx
  256.         or      byte [eax+8],8
  257.         inc     esi
  258.         mov     ebx,[free_additional_memory]
  259.         lea     edx,[ebx+10h]
  260.         cmp     edx,[structures_buffer]
  261.         jae     out_of_memory
  262.         mov     [free_additional_memory],edx
  263.         mov     [ebx+8],eax
  264.         mov     eax,[current_line]
  265.         mov     [ebx+0Ch],eax
  266.         lods    byte [esi]
  267.         cmp     al,86h
  268.         jne     invalid_argument
  269.         lods    word [esi]
  270.         cmp     ax,'('
  271.         jne     invalid_argument
  272.         mov     [ebx+4],esi
  273.         lods    dword [esi]
  274.         lea     esi,[esi+eax+1]
  275.         mov     byte [ebx],80h
  276.         jmp     instruction_assembled
  277. extrn_directive:
  278.         mov     al,[output_format]
  279.         cmp     al,4
  280.         je      extrn_allowed
  281.         cmp     al,5
  282.         jne     illegal_instruction
  283.         bt      [format_flags],0
  284.         jc      illegal_instruction
  285.       extrn_allowed:
  286.         lods    word [esi]
  287.         cmp     ax,'('
  288.         jne     invalid_argument
  289.         mov     ebx,esi
  290.         lods    dword [esi]
  291.         lea     esi,[esi+eax+1]
  292.         mov     edx,[free_additional_memory]
  293.         lea     eax,[edx+0Ch]
  294.         cmp     eax,[structures_buffer]
  295.         jae     out_of_memory
  296.         mov     [free_additional_memory],eax
  297.         mov     byte [edx],81h
  298.         mov     [edx+4],ebx
  299.         lods    byte [esi]
  300.         cmp     al,86h
  301.         jne     invalid_argument
  302.         lods    byte [esi]
  303.         cmp     al,2
  304.         jne     invalid_argument
  305.         lods    dword [esi]
  306.         cmp     eax,0Fh
  307.         jb      invalid_use_of_symbol
  308.         je      reserved_word_used_as_symbol
  309.         inc     esi
  310.         mov     ebx,eax
  311.         xor     ah,ah
  312.         lods    byte [esi]
  313.         cmp     al,':'
  314.         je      get_extrn_size
  315.         dec     esi
  316.         cmp     al,11h
  317.         jne     extrn_size_ok
  318.       get_extrn_size:
  319.         lods    word [esi]
  320.         cmp     al,11h
  321.         jne     invalid_argument
  322.       extrn_size_ok:
  323.         mov     [address_symbol],edx
  324.         movzx   ecx,ah
  325.         mov     [edx+8],ecx
  326.         xor     eax,eax
  327.         xor     edx,edx
  328.         xor     ebp,ebp
  329.         mov     ch,2
  330.         test    [format_flags],8
  331.         jz      make_free_label
  332.         mov     ch,4
  333.         jmp     make_free_label
  334. mark_relocation:
  335.         cmp     [value_type],0
  336.         je      relocation_ok
  337.         cmp     [virtual_data],0
  338.         jne     relocation_ok
  339.         cmp     [output_format],2
  340.         je      mark_mz_relocation
  341.         cmp     [output_format],3
  342.         je      mark_pe_relocation
  343.         cmp     [output_format],4
  344.         je      mark_coff_relocation
  345.         cmp     [output_format],5
  346.         je      mark_elf_relocation
  347.       relocation_ok:
  348.         ret
  349. close_pass:
  350.         mov     al,[output_format]
  351.         cmp     al,3
  352.         je      close_pe
  353.         cmp     al,4
  354.         je      close_coff
  355.         cmp     al,5
  356.         je      close_elf
  357.         ret
  358.  
  359. format_mz:
  360.         mov     edx,[additional_memory]
  361.         push    edi
  362.         mov     edi,edx
  363.         mov     ecx,1Ch shr 2
  364.         xor     eax,eax
  365.         rep     stos dword [edi]
  366.         mov     [free_additional_memory],edi
  367.         pop     edi
  368.         mov     word [edx+0Ch],0FFFFh
  369.         mov     word [edx+10h],1000h
  370.         mov     [code_type],16
  371.         jmp     instruction_assembled
  372. mark_mz_relocation:
  373.         push    eax ebx
  374.         inc     [number_of_relocations]
  375.         mov     ebx,[free_additional_memory]
  376.         mov     eax,edi
  377.         sub     eax,[code_start]
  378.         mov     [ebx],ax
  379.         shr     eax,16
  380.         shl     ax,12
  381.         mov     [ebx+2],ax
  382.         cmp     word [ebx],0FFFFh
  383.         jne     mz_relocation_ok
  384.         inc     word [ebx+2]
  385.         sub     word [ebx],10h
  386.       mz_relocation_ok:
  387.         add     ebx,4
  388.         cmp     ebx,[structures_buffer]
  389.         jae     out_of_memory
  390.         mov     [free_additional_memory],ebx
  391.         pop     ebx eax
  392.         ret
  393. segment_directive:
  394.         cmp     [output_format],2
  395.         jne     illegal_instruction
  396.         cmp     [virtual_data],0
  397.         jne     illegal_instruction
  398.         lods    byte [esi]
  399.         cmp     al,2
  400.         jne     invalid_argument
  401.         lods    dword [esi]
  402.         cmp     eax,0Fh
  403.         jb      invalid_use_of_symbol
  404.         je      reserved_word_used_as_symbol
  405.         inc     esi
  406.         mov     ebx,eax
  407.         mov     eax,edi
  408.         sub     eax,[code_start]
  409.         mov     ecx,0Fh
  410.         add     eax,0Fh
  411.         and     eax,1111b
  412.         sub     ecx,eax
  413.         mov     edx,edi
  414.         xor     al,al
  415.         rep     stos byte [edi]
  416.         mov     dword [org_origin],edi
  417.         mov     dword [org_origin+4],0
  418.         mov     [org_registers],0
  419.         mov     [org_start],edi
  420.         mov     eax,edx
  421.         call    undefined_data
  422.         mov     eax,edi
  423.         sub     eax,[code_start]
  424.         shr     eax,4
  425.         cmp     eax,10000h
  426.         jae     value_out_of_range
  427.         mov     edx,eax
  428.         mov     al,16
  429.         cmp     byte [esi],13h
  430.         jne     segment_type_ok
  431.         inc     esi
  432.         lods    byte [esi]
  433.       segment_type_ok:
  434.         mov     [code_type],al
  435.         mov     eax,edx
  436.         mov     cx,0100h
  437.         xor     edx,edx
  438.         xor     ebp,ebp
  439.         mov     [address_symbol],edx
  440.         jmp     make_free_label
  441. mz_entry:
  442.         lods    byte [esi]
  443.         cmp     al,'('
  444.         jne     invalid_argument
  445.         call    get_word_value
  446.         cmp     [value_type],1
  447.         je      initial_cs_ok
  448.         cmp     [error_line],0
  449.         jne     initial_cs_ok
  450.         mov     eax,[current_line]
  451.         mov     [error_line],eax
  452.         mov     [error],invalid_address
  453.       initial_cs_ok:
  454.         mov     edx,[additional_memory]
  455.         mov     [edx+16h],ax
  456.         lods    byte [esi]
  457.         cmp     al,':'
  458.         jne     invalid_argument
  459.         lods    byte [esi]
  460.         cmp     al,'('
  461.         jne     invalid_argument
  462.         ja      invalid_address
  463.         call    get_word_value
  464.         cmp     [value_type],0
  465.         jne     invalid_use_of_symbol
  466.         mov     edx,[additional_memory]
  467.         mov     [edx+14h],ax
  468.         jmp     instruction_assembled
  469. mz_stack:
  470.         lods    byte [esi]
  471.         cmp     al,'('
  472.         jne     invalid_argument
  473.         call    get_word_value
  474.         cmp     byte [esi],':'
  475.         je      stack_pointer
  476.         cmp     ax,10h
  477.         jb      invalid_value
  478.         cmp     [value_type],0
  479.         jne     invalid_use_of_symbol
  480.         mov     edx,[additional_memory]
  481.         mov     [edx+10h],ax
  482.         jmp     instruction_assembled
  483.       stack_pointer:
  484.         cmp     [value_type],1
  485.         je      initial_ss_ok
  486.         cmp     [error_line],0
  487.         jne     initial_ss_ok
  488.         mov     eax,[current_line]
  489.         mov     [error_line],eax
  490.         mov     [error],invalid_address
  491.       initial_ss_ok:
  492.         mov     edx,[additional_memory]
  493.         mov     [edx+0Eh],ax
  494.         lods    byte [esi]
  495.         cmp     al,':'
  496.         jne     invalid_argument
  497.         lods    byte [esi]
  498.         cmp     al,'('
  499.         jne     invalid_argument
  500.         call    get_word_value
  501.         cmp     [value_type],0
  502.         jne     invalid_use_of_symbol
  503.         mov     edx,[additional_memory]
  504.         mov     [edx+10h],ax
  505.         bts     [format_flags],4
  506.         jmp     instruction_assembled
  507. mz_heap:
  508.         cmp     [output_format],2
  509.         jne     illegal_instruction
  510.         lods    byte [esi]
  511.         call    get_size_operator
  512.         cmp     ah,1
  513.         je      invalid_value
  514.         cmp     ah,2
  515.         ja      invalid_value
  516.         cmp     al,'('
  517.         jne     invalid_argument
  518.         call    get_word_value
  519.         cmp     [value_type],0
  520.         jne     invalid_use_of_symbol
  521.         mov     edx,[additional_memory]
  522.         mov     [edx+0Ch],ax
  523.         jmp     instruction_assembled
  524. write_mz_header:
  525.         mov     edx,[additional_memory]
  526.         bt      [format_flags],4
  527.         jc      mz_stack_ok
  528.         mov     eax,[real_code_size]
  529.         dec     eax
  530.         shr     eax,4
  531.         inc     eax
  532.         mov     [edx+0Eh],ax
  533.         shl     eax,4
  534.         movzx   ecx,word [edx+10h]
  535.         add     eax,ecx
  536.         mov     [real_code_size],eax
  537.       mz_stack_ok:
  538.         mov     edi,[free_additional_memory]
  539.         mov     eax,[number_of_relocations]
  540.         shl     eax,2
  541.         add     eax,1Ch
  542.         sub     edi,eax
  543.         xchg    edi,[free_additional_memory]
  544.         mov     ecx,0Fh
  545.         add     eax,0Fh
  546.         and     eax,1111b
  547.         sub     ecx,eax
  548.         xor     al,al
  549.         rep     stos byte [edi]
  550.         sub     edi,[free_additional_memory]
  551.         mov     ecx,edi
  552.         shr     edi,4
  553.         mov     word [edx],'MZ'         ; signature
  554.         mov     [edx+8],di              ; header size in paragraphs
  555.         mov     eax,[number_of_relocations]
  556.         mov     [edx+6],ax              ; number of relocation entries
  557.         mov     eax,[code_size]
  558.         add     eax,ecx
  559.         mov     esi,eax
  560.         shr     esi,9
  561.         and     eax,1FFh
  562.         inc     si
  563.         or      ax,ax
  564.         jnz     mz_size_ok
  565.         mov     ax,200h
  566.         dec     si
  567.       mz_size_ok:
  568.         mov     [edx+2],ax              ; number of bytes in last page
  569.         mov     [edx+4],si              ; number of pages
  570.         mov     eax,[real_code_size]
  571.         dec     eax
  572.         shr     eax,4
  573.         inc     eax
  574.         mov     esi,[code_size]
  575.         dec     esi
  576.         shr     esi,4
  577.         inc     esi
  578.         sub     eax,esi
  579.         mov     [edx+0Ah],ax            ; minimum memory in addition to code
  580.         add     [edx+0Ch],ax            ; maximum memory in addition to code
  581.         salc
  582.         mov     ah,al
  583.         or      [edx+0Ch],ax
  584.         mov     word [edx+18h],1Ch      ; offset of relocation table
  585.         add     [written_size],ecx
  586.         call    write
  587.         jc      write_failed
  588.         ret
  589.  
  590. make_stub:
  591.         mov     [stub_file],edx
  592.         or      edx,edx
  593.         jnz     stub_from_file
  594.         push    esi
  595.         mov     edx,edi
  596.         xor     eax,eax
  597.         mov     ecx,20h
  598.         rep     stos dword [edi]
  599.         mov     eax,40h+default_stub_end-default_stub
  600.         mov     cx,100h+default_stub_end-default_stub
  601.         mov     word [edx],'MZ'
  602.         mov     word [edx+4],1
  603.         mov     word [edx+2],ax
  604.         mov     word [edx+8],4
  605.         mov     word [edx+0Ah],10h
  606.         mov     word [edx+0Ch],0FFFFh
  607.         mov     word [edx+10h],cx
  608.         mov     word [edx+3Ch],ax
  609.         mov     word [edx+18h],40h
  610.         lea     edi,[edx+40h]
  611.         mov     esi,default_stub
  612.         mov     ecx,default_stub_end-default_stub
  613.         rep     movs byte [edi],[esi]
  614.         pop     esi
  615.         jmp     stub_ok
  616.       default_stub:
  617.         use16
  618.         push    cs
  619.         pop     ds
  620.         mov     dx,stub_message-default_stub
  621.         mov     ah,9
  622.         int     21h
  623.         mov     ax,4C01h
  624.         int     21h
  625.       stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
  626.         rq      1
  627.       default_stub_end:
  628.         use32
  629.       stub_from_file:
  630.         push    esi
  631.         mov     esi,edx
  632.         call    open_binary_file
  633.         mov     edx,edi
  634.         mov     ecx,1Ch
  635.         mov     esi,edx
  636.         call    read
  637.         jc      binary_stub
  638.         cmp     word [esi],'MZ'
  639.         jne     binary_stub
  640.         add     edi,1Ch
  641.         movzx   ecx,word [esi+6]
  642.         dec     ecx
  643.         sar     ecx,3
  644.         inc     ecx
  645.         shl     ecx,2
  646.         add     ecx,(40h-1Ch) shr 2
  647.         lea     eax,[edi+ecx*4]
  648.         cmp     edi,[display_buffer]
  649.         jae     out_of_memory
  650.         xor     eax,eax
  651.         rep     stos dword [edi]
  652.         mov     edx,40h
  653.         xchg    dx,[esi+18h]
  654.         xor     al,al
  655.         call    lseek
  656.         movzx   ecx,word [esi+6]
  657.         shl     ecx,2
  658.         lea     edx,[esi+40h]
  659.         call    read
  660.         mov     edx,edi
  661.         sub     edx,esi
  662.         shr     edx,4
  663.         xchg    dx,[esi+8]
  664.         shl     edx,4
  665.         xor     al,al
  666.         call    lseek
  667.         movzx   ecx,word [esi+4]
  668.         dec     ecx
  669.         shl     ecx,9
  670.         movzx   edx,word [esi+2]
  671.         add     ecx,edx
  672.         mov     edx,edi
  673.         sub     ecx,eax
  674.         je      read_stub_code
  675.         jb      stub_code_ok
  676.         push    ecx
  677.         dec     ecx
  678.         shr     ecx,3
  679.         inc     ecx
  680.         shl     ecx,1
  681.         lea     eax,[edi+ecx*4]
  682.         cmp     eax,[display_buffer]
  683.         jae     out_of_memory
  684.         xor     eax,eax
  685.         rep     stos dword [edi]
  686.         pop     ecx
  687.      read_stub_code:
  688.         call    read
  689.      stub_code_ok:
  690.         call    close
  691.         mov     edx,edi
  692.         sub     edx,esi
  693.         mov     ax,dx
  694.         and     ax,1FFh
  695.         mov     [esi+2],ax
  696.         dec     edx
  697.         shr     edx,9
  698.         inc     edx
  699.         mov     [esi+4],dx
  700.         mov     eax,edi
  701.         sub     eax,esi
  702.         mov     [esi+3Ch],eax
  703.         pop     esi
  704.       stub_ok:
  705.         ret
  706.       binary_stub:
  707.         mov     esi,edi
  708.         mov     ecx,40h shr 2
  709.         xor     eax,eax
  710.         rep     stos dword [edi]
  711.         mov     al,2
  712.         xor     edx,edx
  713.         call    lseek
  714.         push    eax
  715.         xor     al,al
  716.         xor     edx,edx
  717.         call    lseek
  718.         mov     ecx,[esp]
  719.         add     ecx,40h+111b
  720.         and     ecx,not 111b
  721.         mov     ax,cx
  722.         and     ax,1FFh
  723.         mov     [esi+2],ax
  724.         lea     eax,[ecx+1FFh]
  725.         and     eax,not 1FFh
  726.         mov     [esi+4],ax
  727.         mov     [esi+3Ch],ecx
  728.         sub     ecx,40h
  729.         mov     eax,10000h
  730.         sub     eax,ecx
  731.         jbe     binary_heap_ok
  732.         shr     eax,4
  733.         mov     [esi+0Ah],ax
  734.       binary_heap_ok:
  735.         mov     word [esi],'MZ'
  736.         mov     word [esi+8],4
  737.         mov     ax,0FFFFh
  738.         mov     [esi+0Ch],ax
  739.         dec     ax
  740.         mov     [esi+10h],ax
  741.         sub     ax,0Eh
  742.         mov     [esi+0Eh],ax
  743.         mov     [esi+16h],ax
  744.         mov     word [esi+14h],100h
  745.         mov     word [esi+18h],40h
  746.         mov     eax,[display_buffer]
  747.         sub     eax,ecx
  748.         cmp     edi,eax
  749.         jae     out_of_memory
  750.         mov     edx,edi
  751.         shr     ecx,2
  752.         xor     eax,eax
  753.         rep     stos dword [edi]
  754.         pop     ecx
  755.         call    read
  756.         call    close
  757.         pop     esi
  758.         ret
  759.  
  760. format_pe:
  761.         xor     edx,edx
  762.         mov     [machine],14Ch
  763.         mov     [subsystem],3
  764.         mov     [subsystem_version],3 + 10 shl 16
  765.         mov     [image_base],400000h
  766.         test    [format_flags],8
  767.         jz      pe_settings
  768.         mov     [machine],8664h
  769.         mov     [subsystem_version],5 + 0 shl 16
  770.         mov     [image_base_high],0
  771.       pe_settings:
  772.         cmp     byte [esi],84h
  773.         je      get_stub_name
  774.         cmp     byte [esi],80h
  775.         je      get_pe_base
  776.         cmp     byte [esi],1Bh
  777.         jne     pe_settings_ok
  778.         lods    byte [esi]
  779.         lods    byte [esi]
  780.         test    al,80h+40h
  781.         jz      subsystem_setting
  782.         cmp     al,80h
  783.         je      dll_flag
  784.         cmp     al,81h
  785.         je      wdm_flag
  786.         jmp     pe_settings
  787.       dll_flag:
  788.         bts     [format_flags],8
  789.         jc      setting_already_specified
  790.         jmp     pe_settings
  791.       wdm_flag:
  792.         bts     [format_flags],9
  793.         jc      setting_already_specified
  794.         jmp     pe_settings
  795.       subsystem_setting:
  796.         bts     [format_flags],7
  797.         jc      setting_already_specified
  798.         and     ax,3Fh
  799.         mov     [subsystem],ax
  800.         cmp     byte [esi],'('
  801.         jne     pe_settings
  802.         inc     esi
  803.         cmp     byte [esi],'.'
  804.         jne     invalid_value
  805.         inc     esi
  806.         push    edx
  807.         cmp     byte [esi+11],0
  808.         jne     invalid_value
  809.         cmp     byte [esi+10],2
  810.         ja      invalid_value
  811.         mov     dx,[esi+8]
  812.         cmp     dx,8000h
  813.         je      zero_version
  814.         mov     eax,[esi+4]
  815.         cmp     dx,7
  816.         jg      invalid_value
  817.         mov     cx,7
  818.         sub     cx,dx
  819.         mov     eax,[esi+4]
  820.         shr     eax,cl
  821.         mov     ebx,eax
  822.         shr     ebx,24
  823.         cmp     bl,100
  824.         jae     invalid_value
  825.         and     eax,0FFFFFFh
  826.         mov     ecx,100
  827.         mul     ecx
  828.         shrd    eax,edx,24
  829.         jnc     version_value_ok
  830.         inc     eax
  831.       version_value_ok:
  832.         shl     eax,16
  833.         mov     ax,bx
  834.         jmp     subsystem_version_ok
  835.       zero_version:
  836.         xor     eax,eax
  837.       subsystem_version_ok:
  838.         pop     edx
  839.         add     esi,13
  840.         mov     [subsystem_version],eax
  841.         jmp     pe_settings
  842.       get_pe_base:
  843.         bts     [format_flags],10
  844.         jc      setting_already_specified
  845.         lods    word [esi]
  846.         cmp     ah,'('
  847.         jne     invalid_argument
  848.         cmp     byte [esi],'.'
  849.         je      invalid_value
  850.         push    edx edi
  851.         add     edi,[stub_size]
  852.         test    [format_flags],8
  853.         jnz     get_pe64_base
  854.         call    get_dword_value
  855.         mov     [image_base],eax
  856.         jmp     pe_base_ok
  857.       get_pe64_base:
  858.         call    get_qword_value
  859.         mov     [image_base],eax
  860.         mov     [image_base_high],edx
  861.       pe_base_ok:
  862.         pop     edi edx
  863.         cmp     [value_type],0
  864.         jne     invalid_use_of_symbol
  865.         cmp     byte [esi],84h
  866.         jne     pe_settings_ok
  867.       get_stub_name:
  868.         lods    byte [esi]
  869.         lods    word [esi]
  870.         cmp     ax,'('
  871.         jne     invalid_argument
  872.         lods    dword [esi]
  873.         mov     edx,esi
  874.         add     esi,eax
  875.         inc     esi
  876.       pe_settings_ok:
  877.         mov     ebp,[stub_size]
  878.         or      ebp,ebp
  879.         jz      make_pe_stub
  880.         cmp     edx,[stub_file]
  881.         je      pe_stub_ok
  882.         sub     edi,[stub_size]
  883.         mov     [code_start],edi
  884.       make_pe_stub:
  885.         call    make_stub
  886.         mov     eax,edi
  887.         sub     eax,[code_start]
  888.         mov     [stub_size],eax
  889.         mov     [code_start],edi
  890.         mov     ebp,eax
  891.       pe_stub_ok:
  892.         mov     edx,edi
  893.         mov     ecx,18h+0E0h
  894.         test    [format_flags],8
  895.         jz      zero_pe_header
  896.         add     ecx,10h
  897.       zero_pe_header:
  898.         add     ebp,ecx
  899.         shr     ecx,2
  900.         xor     eax,eax
  901.         rep     stos dword [edi]
  902.         mov     word [edx],'PE'         ; signature
  903.         mov     ax,[machine]
  904.         mov     word [edx+4],ax
  905.         mov     dword [edx+38h],1000h   ; section alignment
  906.         mov     dword [edx+3Ch],200h    ; file alignment
  907.         mov     word [edx+40h],1        ; OS version
  908.         mov     eax,[subsystem_version]
  909.         mov     [edx+48h],eax
  910.         mov     ax,[subsystem]
  911.         mov     [edx+5Ch],ax
  912.         cmp     ax,1
  913.         jne     pe_alignment_ok
  914.         mov     eax,20h
  915.         mov     dword [edx+38h],eax
  916.         mov     dword [edx+3Ch],eax
  917.       pe_alignment_ok:
  918.         mov     word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8
  919.         test    [format_flags],8
  920.         jnz     init_pe64_specific
  921.         mov     dword [edx+14h],0E0h    ; size of optional header
  922.         mov     dword [edx+16h],10B010Eh; flags and magic value
  923.         mov     eax,[image_base]
  924.         mov     dword [edx+34h],eax
  925.         mov     dword [edx+60h],1000h   ; stack reserve
  926.         mov     dword [edx+64h],1000h   ; stack commit
  927.         mov     dword [edx+68h],10000h  ; heap reserve
  928.         mov     dword [edx+6Ch],0       ; heap commit
  929.         mov     dword [edx+74h],16      ; number of directories
  930.         jmp     pe_header_ok
  931.       init_pe64_specific:
  932.         mov     dword [edx+14h],0F0h    ; size of optional header
  933.         mov     dword [edx+16h],20B002Eh; flags and magic value
  934.         mov     eax,[image_base]
  935.         mov     dword [edx+30h],eax
  936.         mov     eax,[image_base_high]
  937.         mov     dword [edx+34h],eax
  938.         mov     dword [edx+60h],1000h   ; stack reserve
  939.         mov     dword [edx+68h],1000h   ; stack commit
  940.         mov     dword [edx+70h],10000h  ; heap reserve
  941.         mov     dword [edx+78h],0       ; heap commit
  942.         mov     dword [edx+84h],16      ; number of directories
  943.       pe_header_ok:
  944.         bsf     ecx,[edx+3Ch]
  945.         imul    ebx,[number_of_sections],28h
  946.         or      ebx,ebx
  947.         jnz     reserve_space_for_section_headers
  948.         mov     ebx,28h
  949.       reserve_space_for_section_headers:
  950.         add     ebx,ebp
  951.         dec     ebx
  952.         shr     ebx,cl
  953.         inc     ebx
  954.         shl     ebx,cl
  955.         sub     ebx,ebp
  956.         mov     ecx,ebx
  957.         mov     eax,[display_buffer]
  958.         sub     eax,ecx
  959.         cmp     edi,eax
  960.         jae     out_of_memory
  961.         shr     ecx,2
  962.         xor     eax,eax
  963.         rep     stos dword [edi]
  964.         mov     eax,edi
  965.         sub     eax,[code_start]
  966.         add     eax,[stub_size]
  967.         mov     [edx+54h],eax           ; size of headers
  968.         mov     ecx,[edx+38h]
  969.         dec     ecx
  970.         add     eax,ecx
  971.         not     ecx
  972.         and     eax,ecx
  973.         bt      [format_flags],8
  974.         jc      pe_entry_init_ok
  975.         mov     [edx+28h],eax           ; entry point rva
  976.       pe_entry_init_ok:
  977.         mov     [number_of_sections],0
  978.         movzx   ebx,word [edx+14h]
  979.         lea     ebx,[edx+18h+ebx]
  980.         mov     [current_section],ebx
  981.         mov     dword [ebx],'.fla'
  982.         mov     dword [ebx+4],'t'
  983.         mov     [ebx+14h],edi
  984.         mov     [ebx+0Ch],eax
  985.         mov     dword [ebx+24h],0E0000060h
  986.         xor     ecx,ecx
  987.         not     eax
  988.         not     ecx
  989.         add     eax,1
  990.         adc     ecx,0
  991.         add     eax,edi
  992.         adc     ecx,0
  993.         test    [format_flags],8
  994.         jnz     pe64_org
  995.         sub     eax,[edx+34h]
  996.         sbb     ecx,0
  997.         mov     [labels_type],2
  998.         mov     [code_type],32
  999.         jmp     pe_org_ok
  1000.       pe64_org:
  1001.         sub     eax,[edx+30h]
  1002.         sbb     ecx,[edx+34h]
  1003.         mov     [labels_type],4
  1004.         mov     [code_type],64
  1005.       pe_org_ok:
  1006.         mov     dword [org_origin],eax
  1007.         mov     dword [org_origin+4],ecx
  1008.         mov     [org_registers],0
  1009.         mov     [org_start],edi
  1010.         bt      [format_flags],8
  1011.         jnc     dll_flag_ok
  1012.         or      dword [edx+16h],2000h
  1013.       dll_flag_ok:
  1014.         bt      [format_flags],9
  1015.         jnc     wdm_flag_ok
  1016.         or      word [edx+5Eh],2000h
  1017.       wdm_flag_ok:
  1018.         jmp     instruction_assembled
  1019. pe_section:
  1020.         call    close_pe_section
  1021.         bts     [format_flags],5
  1022.         lea     ecx,[ebx+28h]
  1023.         add     edx,[edx+54h]
  1024.         sub     edx,[stub_size]
  1025.         cmp     ecx,edx
  1026.         jbe     new_section
  1027.         lea     ebx,[edx-28h]
  1028.         or      [next_pass_needed],-1
  1029.         push    edi
  1030.         mov     edi,ebx
  1031.         mov     ecx,28h shr 4
  1032.         xor     eax,eax
  1033.         rep     stos dword [edi]
  1034.         pop     edi
  1035.       new_section:
  1036.         mov     [ebx+0Ch],eax
  1037.         lods    word [esi]
  1038.         cmp     ax,'('
  1039.         jne     invalid_argument
  1040.         lea     edx,[esi+4]
  1041.         mov     ecx,[esi]
  1042.         lea     esi,[esi+4+ecx+1]
  1043.         cmp     ecx,8
  1044.         ja      name_too_long
  1045.         xor     eax,eax
  1046.         mov     [ebx],eax
  1047.         mov     [ebx+4],eax
  1048.         push    esi edi
  1049.         mov     edi,ebx
  1050.         mov     esi,edx
  1051.         rep     movs byte [edi],[esi]
  1052.         pop     edi esi
  1053.         mov     dword [ebx+24h],0
  1054.         mov     [ebx+14h],edi
  1055.         mov     edx,[code_start]
  1056.         mov     eax,edi
  1057.         xor     ecx,ecx
  1058.         sub     eax,[ebx+0Ch]
  1059.         sbb     ecx,0
  1060.         test    [format_flags],8
  1061.         jnz     pe64_section_org
  1062.         sub     eax,[edx+34h]
  1063.         sbb     ecx,0
  1064.         mov     [labels_type],2
  1065.         mov     [code_type],32
  1066.         jmp     pe_section_org_ok
  1067.       pe64_section_org:
  1068.         sub     eax,[edx+30h]
  1069.         sbb     ecx,[edx+34h]
  1070.         mov     [labels_type],4
  1071.         mov     [code_type],64
  1072.       pe_section_org_ok:
  1073.         mov     dword [org_origin],eax
  1074.         mov     dword [org_origin+4],ecx
  1075.         mov     [org_registers],0
  1076.         mov     [org_start],edi
  1077.       get_section_flags:
  1078.         lods    byte [esi]
  1079.         cmp     al,1Ah
  1080.         je      set_directory
  1081.         cmp     al,19h
  1082.         je      section_flag
  1083.         dec     esi
  1084.         jmp     instruction_assembled
  1085.       set_directory:
  1086.         movzx   eax,byte [esi]
  1087.         inc     esi
  1088.         mov     ecx,ebx
  1089.         test    [format_flags],8
  1090.         jnz     pe64_directory
  1091.         xchg    ecx,[edx+78h+eax*8]
  1092.         mov     dword [edx+78h+eax*8+4],-1
  1093.         jmp     pe_directory_set
  1094.       pe64_directory:
  1095.         xchg    ecx,[edx+88h+eax*8]
  1096.         mov     dword [edx+88h+eax*8+4],-1
  1097.       pe_directory_set:
  1098.         or      ecx,ecx
  1099.         jnz     data_already_defined
  1100.         push    ebx edx
  1101.         call    generate_pe_data
  1102.         pop     edx ebx
  1103.         jmp     get_section_flags
  1104.       section_flag:
  1105.         lods    byte [esi]
  1106.         mov     cl,al
  1107.         mov     eax,1
  1108.         shl     eax,cl
  1109.         test    dword [ebx+24h],eax
  1110.         jnz     setting_already_specified
  1111.         or      dword [ebx+24h],eax
  1112.         jmp     get_section_flags
  1113.       close_pe_section:
  1114.         mov     ebx,[current_section]
  1115.         mov     edx,[code_start]
  1116.         mov     eax,edi
  1117.         sub     eax,[ebx+14h]
  1118.         jnz     finish_section
  1119.         bt      [format_flags],5
  1120.         jc      finish_section
  1121.         mov     eax,[ebx+0Ch]
  1122.         ret
  1123.       finish_section:
  1124.         mov     [ebx+8],eax
  1125.         cmp     edi,[undefined_data_end]
  1126.         jne     align_section
  1127.         cmp     dword [edx+38h],1000h
  1128.         jb      align_section
  1129.         mov     edi,[undefined_data_start]
  1130.       align_section:
  1131.         mov     [undefined_data_end],0
  1132.         mov     ebp,edi
  1133.         sub     ebp,[ebx+14h]
  1134.         mov     ecx,[edx+3Ch]
  1135.         dec     ecx
  1136.         lea     eax,[ebp+ecx]
  1137.         not     ecx
  1138.         and     eax,ecx
  1139.         mov     [ebx+10h],eax
  1140.         sub     eax,ebp
  1141.         mov     ecx,eax
  1142.         xor     al,al
  1143.         rep     stos byte [edi]
  1144.         mov     eax,[code_start]
  1145.         sub     eax,[stub_size]
  1146.         sub     [ebx+14h],eax
  1147.         mov     eax,[ebx+8]
  1148.         or      eax,eax
  1149.         jz      udata_ok
  1150.         cmp     dword [ebx+10h],0
  1151.         jne     udata_ok
  1152.         or      byte [ebx+24h],80h
  1153.       udata_ok:
  1154.         mov     ecx,[edx+38h]
  1155.         dec     ecx
  1156.         add     eax,ecx
  1157.         not     ecx
  1158.         and     eax,ecx
  1159.         add     eax,[ebx+0Ch]
  1160.         add     ebx,28h
  1161.         mov     [current_section],ebx
  1162.         inc     word [number_of_sections]
  1163.         jz      format_limitations_exceeded
  1164.         ret
  1165. data_directive:
  1166.         cmp     [output_format],3
  1167.         jne     illegal_instruction
  1168.         lods    byte [esi]
  1169.         cmp     al,1Ah
  1170.         je      predefined_data_type
  1171.         cmp     al,'('
  1172.         jne     invalid_argument
  1173.         call    get_byte_value
  1174.         cmp     al,16
  1175.         jb      data_type_ok
  1176.         jmp     invalid_value
  1177.       predefined_data_type:
  1178.         movzx   eax,byte [esi]
  1179.         inc     esi
  1180.       data_type_ok:
  1181.         mov     ebx,[current_section]
  1182.         mov     ecx,edi
  1183.         sub     ecx,[ebx+14h]
  1184.         add     ecx,[ebx+0Ch]
  1185.         mov     edx,[code_start]
  1186.         test    [format_flags],8
  1187.         jnz     pe64_data
  1188.         xchg    ecx,[edx+78h+eax*8]
  1189.         jmp     init_pe_data
  1190.       pe64_data:
  1191.         xchg    ecx,[edx+88h+eax*8]
  1192.       init_pe_data:
  1193.         or      ecx,ecx
  1194.         jnz     data_already_defined
  1195.         call    allocate_structure_data
  1196.         mov     word [ebx],data_directive-assembler
  1197.         mov     [ebx+2],al
  1198.         mov     edx,[current_line]
  1199.         mov     [ebx+4],edx
  1200.         call    generate_pe_data
  1201.         jmp     instruction_assembled
  1202.       end_data:
  1203.         cmp     [output_format],3
  1204.         jne     illegal_instruction
  1205.         call    find_structure_data
  1206.         jc      unexpected_instruction
  1207.         movzx   eax,byte [ebx+2]
  1208.         mov     edx,[current_section]
  1209.         mov     ecx,edi
  1210.         sub     ecx,[edx+14h]
  1211.         add     ecx,[edx+0Ch]
  1212.         mov     edx,[code_start]
  1213.         test    [format_flags],8
  1214.         jnz     end_pe64_data
  1215.         sub     ecx,[edx+78h+eax*8]
  1216.         mov     [edx+78h+eax*8+4],ecx
  1217.         jmp     remove_structure_data
  1218.       end_pe64_data:
  1219.         sub     ecx,[edx+88h+eax*8]
  1220.         mov     [edx+88h+eax*8+4],ecx
  1221.         jmp     remove_structure_data
  1222. pe_entry:
  1223.         lods    byte [esi]
  1224.         cmp     al,'('
  1225.         jne     invalid_argument
  1226.         cmp     byte [esi],'.'
  1227.         je      invalid_value
  1228.         test    [format_flags],8
  1229.         jnz     pe64_entry
  1230.         call    get_dword_value
  1231.         cmp     [value_type],2
  1232.         je      pe_entry_ok
  1233.         cmp     [error_line],0
  1234.         jne     pe_entry_ok
  1235.         mov     eax,[current_line]
  1236.         mov     [error_line],eax
  1237.         mov     [error],invalid_address
  1238.       pe_entry_ok:
  1239.         mov     edx,[code_start]
  1240.         sub     eax,[edx+34h]
  1241.         mov     [edx+28h],eax
  1242.         jmp     instruction_assembled
  1243.       pe64_entry:
  1244.         call    get_qword_value
  1245.         cmp     [value_type],4
  1246.         je      pe64_entry_ok
  1247.         cmp     [error_line],0
  1248.         jne     pe64_entry_ok
  1249.         mov     eax,[current_line]
  1250.         mov     [error_line],eax
  1251.         mov     [error],invalid_address
  1252.       pe64_entry_ok:
  1253.         mov     ecx,[code_start]
  1254.         sub     eax,[ecx+30h]
  1255.         sbb     edx,[ecx+34h]
  1256.         jnz     value_out_of_range
  1257.         mov     [ecx+28h],eax
  1258.         jmp     instruction_assembled
  1259. pe_stack:
  1260.         lods    byte [esi]
  1261.         cmp     al,'('
  1262.         jne     invalid_argument
  1263.         cmp     byte [esi],'.'
  1264.         je      invalid_value
  1265.         test    [format_flags],8
  1266.         jnz     pe64_stack
  1267.         call    get_dword_value
  1268.         cmp     [value_type],0
  1269.         jne     invalid_use_of_symbol
  1270.         mov     edx,[code_start]
  1271.         mov     [edx+60h],eax
  1272.         cmp     byte [esi],','
  1273.         jne     default_stack_commit
  1274.         lods    byte [esi]
  1275.         lods    byte [esi]
  1276.         cmp     al,'('
  1277.         jne     invalid_argument
  1278.         cmp     byte [esi],'.'
  1279.         je      invalid_value
  1280.         call    get_dword_value
  1281.         cmp     [value_type],0
  1282.         jne     invalid_use_of_symbol
  1283.         mov     edx,[code_start]
  1284.         mov     [edx+64h],eax
  1285.         cmp     eax,[edx+60h]
  1286.         ja      value_out_of_range
  1287.         jmp     instruction_assembled
  1288.       default_stack_commit:
  1289.         mov     dword [edx+64h],1000h
  1290.         mov     eax,[edx+60h]
  1291.         cmp     eax,1000h
  1292.         ja      instruction_assembled
  1293.         mov     dword [edx+64h],eax
  1294.         jmp     instruction_assembled
  1295.       pe64_stack:
  1296.         call    get_qword_value
  1297.         cmp     [value_type],0
  1298.         jne     invalid_use_of_symbol
  1299.         mov     ecx,[code_start]
  1300.         mov     [ecx+60h],eax
  1301.         mov     [ecx+64h],edx
  1302.         cmp     byte [esi],','
  1303.         jne     default_pe64_stack_commit
  1304.         lods    byte [esi]
  1305.         lods    byte [esi]
  1306.         cmp     al,'('
  1307.         jne     invalid_argument
  1308.         cmp     byte [esi],'.'
  1309.         je      invalid_value
  1310.         call    get_qword_value
  1311.         cmp     [value_type],0
  1312.         jne     invalid_use_of_symbol
  1313.         mov     ecx,[code_start]
  1314.         mov     [ecx+68h],eax
  1315.         mov     [ecx+6Ch],edx
  1316.         cmp     edx,[ecx+64h]
  1317.         ja      value_out_of_range
  1318.         jb      instruction_assembled
  1319.         cmp     eax,[edx+60h]
  1320.         ja      value_out_of_range
  1321.         jmp     instruction_assembled
  1322.       default_pe64_stack_commit:
  1323.         mov     dword [edx+68h],1000h
  1324.         cmp     dword [edx+64h],0
  1325.         jne     instruction_assembled
  1326.         mov     eax,[edx+60h]
  1327.         cmp     eax,1000h
  1328.         ja      instruction_assembled
  1329.         mov     dword [edx+68h],eax
  1330.         jmp     instruction_assembled
  1331. pe_heap:
  1332.         lods    byte [esi]
  1333.         cmp     al,'('
  1334.         jne     invalid_argument
  1335.         cmp     byte [esi],'.'
  1336.         je      invalid_value
  1337.         test    [format_flags],8
  1338.         jnz     pe64_heap
  1339.         call    get_dword_value
  1340.         cmp     [value_type],0
  1341.         jne     invalid_use_of_symbol
  1342.         mov     edx,[code_start]
  1343.         mov     [edx+68h],eax
  1344.         cmp     byte [esi],','
  1345.         jne     instruction_assembled
  1346.         lods    byte [esi]
  1347.         lods    byte [esi]
  1348.         cmp     al,'('
  1349.         jne     invalid_argument
  1350.         cmp     byte [esi],'.'
  1351.         je      invalid_value
  1352.         call    get_dword_value
  1353.         cmp     [value_type],0
  1354.         jne     invalid_use_of_symbol
  1355.         mov     edx,[code_start]
  1356.         mov     [edx+6Ch],eax
  1357.         cmp     eax,[edx+68h]
  1358.         ja      value_out_of_range
  1359.         jmp     instruction_assembled
  1360.       pe64_heap:
  1361.         call    get_qword_value
  1362.         cmp     [value_type],0
  1363.         jne     invalid_use_of_symbol
  1364.         mov     ecx,[code_start]
  1365.         mov     [ecx+70h],eax
  1366.         mov     [ecx+74h],edx
  1367.         cmp     byte [esi],','
  1368.         jne     instruction_assembled
  1369.         lods    byte [esi]
  1370.         lods    byte [esi]
  1371.         cmp     al,'('
  1372.         jne     invalid_argument
  1373.         cmp     byte [esi],'.'
  1374.         je      invalid_value
  1375.         call    get_qword_value
  1376.         cmp     [value_type],0
  1377.         jne     invalid_use_of_symbol
  1378.         mov     ecx,[code_start]
  1379.         mov     [ecx+78h],eax
  1380.         mov     [ecx+7Ch],edx
  1381.         cmp     edx,[ecx+74h]
  1382.         ja      value_out_of_range
  1383.         jb      instruction_assembled
  1384.         cmp     eax,[edx+70h]
  1385.         ja      value_out_of_range
  1386.         jmp     instruction_assembled
  1387. mark_pe_relocation:
  1388.         push    eax ebx
  1389.         mov     ebx,[current_section]
  1390.         mov     eax,edi
  1391.         sub     eax,[ebx+14h]
  1392.         add     eax,[ebx+0Ch]
  1393.         mov     ebx,[free_additional_memory]
  1394.         inc     [number_of_relocations]
  1395.         jz      invalid_use_of_symbol
  1396.         mov     [ebx],eax
  1397.         add     ebx,4
  1398.         cmp     ebx,[structures_buffer]
  1399.         jae     out_of_memory
  1400.         mov     [free_additional_memory],ebx
  1401.         pop     ebx eax
  1402.         ret
  1403. generate_pe_data:
  1404.         cmp     al,2
  1405.         je      make_pe_resource
  1406.         cmp     al,5
  1407.         je      make_pe_fixups
  1408.         ret
  1409. make_pe_resource:
  1410.         cmp     byte [esi],82h
  1411.         jne     resource_done
  1412.         inc     esi
  1413.         lods    word [esi]
  1414.         cmp     ax,'('
  1415.         jne     invalid_argument
  1416.         lods    dword [esi]
  1417.         mov     edx,esi
  1418.         lea     esi,[esi+eax+1]
  1419.         cmp     [next_pass_needed],0
  1420.         je      resource_from_file
  1421.         cmp     [current_pass],0
  1422.         jne     reserve_space_for_resource
  1423.         mov     [resource_size],0
  1424.       reserve_space_for_resource:
  1425.         add     edi,[resource_size]
  1426.         cmp     edi,[display_buffer]
  1427.         ja      out_of_memory
  1428.         jmp     resource_done
  1429.       resource_from_file:
  1430.         push    esi
  1431.         mov     esi,edx
  1432.         call    open_binary_file
  1433.         push    ebx
  1434.         mov     esi,[free_additional_memory]
  1435.         lea     eax,[esi+20h]
  1436.         cmp     eax,[structures_buffer]
  1437.         ja      out_of_memory
  1438.         mov     edx,esi
  1439.         mov     ecx,20h
  1440.         call    read
  1441.         jc      invalid_file_format
  1442.         xor     eax,eax
  1443.         cmp     [esi],eax
  1444.         jne     invalid_file_format
  1445.         mov     ax,0FFFFh
  1446.         cmp     [esi+8],eax
  1447.         jne     invalid_file_format
  1448.         cmp     [esi+12],eax
  1449.         jne     invalid_file_format
  1450.         mov     eax,20h
  1451.         cmp     [esi+4],eax
  1452.         jne     invalid_file_format
  1453.       read_resource_headers:
  1454.         test    eax,11b
  1455.         jz      resource_file_alignment_ok
  1456.         mov     edx,4
  1457.         and     eax,11b
  1458.         sub     edx,eax
  1459.         mov     al,1
  1460.         call    lseek
  1461.       resource_file_alignment_ok:
  1462.         mov     [esi],eax
  1463.         lea     edx,[esi+12]
  1464.         mov     ecx,8
  1465.         call    read
  1466.         jc      resource_headers_ok
  1467.         mov     ecx,[esi+16]
  1468.         add     [esi],ecx
  1469.         lea     edx,[esi+20]
  1470.         sub     ecx,8
  1471.         mov     [esi+16],ecx
  1472.         lea     eax,[edx+ecx]
  1473.         cmp     eax,[structures_buffer]
  1474.         ja      out_of_memory
  1475.         call    read
  1476.         jc      invalid_file_format
  1477.         mov     edx,[esi]
  1478.         add     edx,[esi+12]
  1479.         mov     eax,[esi+16]
  1480.         lea     ecx,[esi+20]
  1481.         lea     esi,[ecx+eax]
  1482.         add     ecx,2
  1483.         cmp     word [ecx-2],0FFFFh
  1484.         je      resource_header_type_ok
  1485.       check_resource_header_type:
  1486.         cmp     ecx,esi
  1487.         jae     invalid_file_format
  1488.         cmp     word [ecx],0
  1489.         je      resource_header_type_ok
  1490.         add     ecx,2
  1491.         jmp     check_resource_header_type
  1492.       resource_header_type_ok:
  1493.         add     ecx,2
  1494.         cmp     word [ecx],0FFFFh
  1495.         je      resource_header_name_ok
  1496.       check_resource_header_name:
  1497.         cmp     ecx,esi
  1498.         jae     invalid_file_format
  1499.         cmp     word [ecx],0
  1500.         je      resource_header_name_ok
  1501.         add     ecx,2
  1502.         jmp     check_resource_header_name
  1503.       resource_header_name_ok:
  1504.         xor     al,al
  1505.         call    lseek
  1506.         jmp     read_resource_headers
  1507.       resource_headers_ok:
  1508.         xor     eax,eax
  1509.         mov     [esi],eax
  1510.         mov     [resource_data],edi
  1511.         lea     eax,[edi+16]
  1512.         cmp     eax,[display_buffer]
  1513.         jae     out_of_memory
  1514.         xor     eax,eax
  1515.         stos    dword [edi]
  1516.         call    make_timestamp
  1517.         stos    dword [edi]
  1518.         xor     eax,eax
  1519.         stos    dword [edi]
  1520.         stos    dword [edi]
  1521.         xor     ebx,ebx
  1522.       make_type_name_directory:
  1523.         mov     esi,[free_additional_memory]
  1524.         xor     edx,edx
  1525.       find_type_name:
  1526.         cmp     dword [esi],0
  1527.         je      type_name_ok
  1528.         add     esi,20
  1529.         cmp     word [esi],0FFFFh
  1530.         je      check_next_type_name
  1531.         or      ebx,ebx
  1532.         jz      check_this_type_name
  1533.         xor     ecx,ecx
  1534.       compare_with_previous_type_name:
  1535.         mov     ax,[esi+ecx]
  1536.         cmp     ax,[ebx+ecx]
  1537.         ja      check_this_type_name
  1538.         jb      check_next_type_name
  1539.         add     ecx,2
  1540.         mov     ax,[esi+ecx]
  1541.         or      ax,[ebx+ecx]
  1542.         jnz     compare_with_previous_type_name
  1543.         jmp     check_next_type_name
  1544.       check_this_type_name:
  1545.         or      edx,edx
  1546.         jz      type_name_found
  1547.         xor     ecx,ecx
  1548.       compare_with_current_type_name:
  1549.         mov     ax,[esi+ecx]
  1550.         cmp     ax,[edx+ecx]
  1551.         ja      check_next_type_name
  1552.         jb      type_name_found
  1553.         add     ecx,2
  1554.         mov     ax,[esi+ecx]
  1555.         or      ax,[edx+ecx]
  1556.         jnz     compare_with_current_type_name
  1557.         jmp     same_type_name
  1558.       type_name_found:
  1559.         mov     edx,esi
  1560.       same_type_name:
  1561.         mov     [esi-16],edi
  1562.       check_next_type_name:
  1563.         mov     eax,[esi-4]
  1564.         add     esi,eax
  1565.         jmp     find_type_name
  1566.       type_name_ok:
  1567.         or      edx,edx
  1568.         jz      type_name_directory_done
  1569.         mov     ebx,edx
  1570.       make_type_name_entry:
  1571.         mov     eax,[resource_data]
  1572.         inc     word [eax+12]
  1573.         lea     eax,[edi+8]
  1574.         cmp     eax,[display_buffer]
  1575.         jae     out_of_memory
  1576.         mov     eax,ebx
  1577.         stos    dword [edi]
  1578.         xor     eax,eax
  1579.         stos    dword [edi]
  1580.         jmp     make_type_name_directory
  1581.       type_name_directory_done:
  1582.         mov     ebx,-1
  1583.       make_type_id_directory:
  1584.         mov     esi,[free_additional_memory]
  1585.         mov     edx,10000h
  1586.       find_type_id:
  1587.         cmp     dword [esi],0
  1588.         je      type_id_ok
  1589.         add     esi,20
  1590.         cmp     word [esi],0FFFFh
  1591.         jne     check_next_type_id
  1592.         movzx   eax,word [esi+2]
  1593.         cmp     eax,ebx
  1594.         jle     check_next_type_id
  1595.         cmp     eax,edx
  1596.         jg      check_next_type_id
  1597.         mov     edx,eax
  1598.         mov     [esi-16],edi
  1599.       check_next_type_id:
  1600.         mov     eax,[esi-4]
  1601.         add     esi,eax
  1602.         jmp     find_type_id
  1603.       type_id_ok:
  1604.         cmp     edx,10000h
  1605.         je      type_id_directory_done
  1606.         mov     ebx,edx
  1607.       make_type_id_entry:
  1608.         mov     eax,[resource_data]
  1609.         inc     word [eax+14]
  1610.         lea     eax,[edi+8]
  1611.         cmp     eax,[display_buffer]
  1612.         jae     out_of_memory
  1613.         mov     eax,ebx
  1614.         stos    dword [edi]
  1615.         xor     eax,eax
  1616.         stos    dword [edi]
  1617.         jmp     make_type_id_directory
  1618.       type_id_directory_done:
  1619.         mov     esi,[resource_data]
  1620.         add     esi,10h
  1621.         mov     ecx,[esi-4]
  1622.         or      cx,cx
  1623.         jz      resource_directories_ok
  1624.       make_resource_directories:
  1625.         push    ecx
  1626.         push    edi
  1627.         mov     edx,edi
  1628.         sub     edx,[resource_data]
  1629.         bts     edx,31
  1630.         mov     [esi+4],edx
  1631.         lea     eax,[edi+16]
  1632.         cmp     eax,[display_buffer]
  1633.         jae     out_of_memory
  1634.         xor     eax,eax
  1635.         stos    dword [edi]
  1636.         call    make_timestamp
  1637.         stos    dword [edi]
  1638.         xor     eax,eax
  1639.         stos    dword [edi]
  1640.         stos    dword [edi]
  1641.         mov     ebp,esi
  1642.         xor     ebx,ebx
  1643.       make_resource_name_directory:
  1644.         mov     esi,[free_additional_memory]
  1645.         xor     edx,edx
  1646.       find_resource_name:
  1647.         cmp     dword [esi],0
  1648.         je      resource_name_ok
  1649.         push    esi
  1650.         cmp     [esi+4],ebp
  1651.         jne     check_next_resource_name
  1652.         add     esi,20
  1653.         call    skip_resource_name
  1654.         cmp     word [esi],0FFFFh
  1655.         je      check_next_resource_name
  1656.         or      ebx,ebx
  1657.         jz      check_this_resource_name
  1658.         xor     ecx,ecx
  1659.       compare_with_previous_resource_name:
  1660.         mov     ax,[esi+ecx]
  1661.         cmp     ax,[ebx+ecx]
  1662.         ja      check_this_resource_name
  1663.         jb      check_next_resource_name
  1664.         add     ecx,2
  1665.         mov     ax,[esi+ecx]
  1666.         or      ax,[ebx+ecx]
  1667.         jnz     compare_with_previous_resource_name
  1668.         jmp     check_next_resource_name
  1669.       skip_resource_name:
  1670.         cmp     word [esi],0FFFFh
  1671.         jne     skip_unicode_string
  1672.         add     esi,4
  1673.         ret
  1674.       skip_unicode_string:
  1675.         add     esi,2
  1676.         cmp     word [esi-2],0
  1677.         jne     skip_unicode_string
  1678.         ret
  1679.       check_this_resource_name:
  1680.         or      edx,edx
  1681.         jz      resource_name_found
  1682.         xor     ecx,ecx
  1683.       compare_with_current_resource_name:
  1684.         mov     ax,[esi+ecx]
  1685.         cmp     ax,[edx+ecx]
  1686.         ja      check_next_resource_name
  1687.         jb      resource_name_found
  1688.         add     ecx,2
  1689.         mov     ax,[esi+ecx]
  1690.         or      ax,[edx+ecx]
  1691.         jnz     compare_with_current_resource_name
  1692.         jmp     same_resource_name
  1693.       resource_name_found:
  1694.         mov     edx,esi
  1695.       same_resource_name:
  1696.         mov     eax,[esp]
  1697.         mov     [eax+8],edi
  1698.       check_next_resource_name:
  1699.         pop     esi
  1700.         mov     eax,[esi+16]
  1701.         lea     esi,[esi+20+eax]
  1702.         jmp     find_resource_name
  1703.       resource_name_ok:
  1704.         or      edx,edx
  1705.         jz      resource_name_directory_done
  1706.         mov     ebx,edx
  1707.       make_resource_name_entry:
  1708.         mov     eax,[esp]
  1709.         inc     word [eax+12]
  1710.         lea     eax,[edi+8]
  1711.         cmp     eax,[display_buffer]
  1712.         jae     out_of_memory
  1713.         mov     eax,ebx
  1714.         stos    dword [edi]
  1715.         xor     eax,eax
  1716.         stos    dword [edi]
  1717.         jmp     make_resource_name_directory
  1718.       resource_name_directory_done:
  1719.         mov     ebx,-1
  1720.       make_resource_id_directory:
  1721.         mov     esi,[free_additional_memory]
  1722.         mov     edx,10000h
  1723.       find_resource_id:
  1724.         cmp     dword [esi],0
  1725.         je      resource_id_ok
  1726.         push    esi
  1727.         cmp     [esi+4],ebp
  1728.         jne     check_next_resource_id
  1729.         add     esi,20
  1730.         call    skip_resource_name
  1731.         cmp     word [esi],0FFFFh
  1732.         jne     check_next_resource_id
  1733.         movzx   eax,word [esi+2]
  1734.         cmp     eax,ebx
  1735.         jle     check_next_resource_id
  1736.         cmp     eax,edx
  1737.         jg      check_next_resource_id
  1738.         mov     edx,eax
  1739.         mov     eax,[esp]
  1740.         mov     [eax+8],edi
  1741.       check_next_resource_id:
  1742.         pop     esi
  1743.         mov     eax,[esi+16]
  1744.         lea     esi,[esi+20+eax]
  1745.         jmp     find_resource_id
  1746.       resource_id_ok:
  1747.         cmp     edx,10000h
  1748.         je      resource_id_directory_done
  1749.         mov     ebx,edx
  1750.       make_resource_id_entry:
  1751.         mov     eax,[esp]
  1752.         inc     word [eax+14]
  1753.         lea     eax,[edi+8]
  1754.         cmp     eax,[display_buffer]
  1755.         jae     out_of_memory
  1756.         mov     eax,ebx
  1757.         stos    dword [edi]
  1758.         xor     eax,eax
  1759.         stos    dword [edi]
  1760.         jmp     make_resource_id_directory
  1761.       resource_id_directory_done:
  1762.         pop     eax
  1763.         mov     esi,ebp
  1764.         pop     ecx
  1765.         add     esi,8
  1766.         dec     cx
  1767.         jnz     make_resource_directories
  1768.       resource_directories_ok:
  1769.         shr     ecx,16
  1770.         jnz     make_resource_directories
  1771.         mov     esi,[resource_data]
  1772.         add     esi,10h
  1773.         movzx   eax,word [esi-4]
  1774.         movzx   edx,word [esi-2]
  1775.         add     eax,edx
  1776.         lea     esi,[esi+eax*8]
  1777.         push    edi                     ; address of language directories
  1778.       update_resource_directories:
  1779.         cmp     esi,[esp]
  1780.         je      resource_directories_updated
  1781.         add     esi,10h
  1782.         mov     ecx,[esi-4]
  1783.         or      cx,cx
  1784.         jz      language_directories_ok
  1785.       make_language_directories:
  1786.         push    ecx
  1787.         push    edi
  1788.         mov     edx,edi
  1789.         sub     edx,[resource_data]
  1790.         bts     edx,31
  1791.         mov     [esi+4],edx
  1792.         lea     eax,[edi+16]
  1793.         cmp     eax,[display_buffer]
  1794.         jae     out_of_memory
  1795.         xor     eax,eax
  1796.         stos    dword [edi]
  1797.         call    make_timestamp
  1798.         stos    dword [edi]
  1799.         xor     eax,eax
  1800.         stos    dword [edi]
  1801.         stos    dword [edi]
  1802.         mov     ebp,esi
  1803.         mov     ebx,-1
  1804.       make_language_id_directory:
  1805.         mov     esi,[free_additional_memory]
  1806.         mov     edx,10000h
  1807.       find_language_id:
  1808.         cmp     dword [esi],0
  1809.         je      language_id_ok
  1810.         push    esi
  1811.         cmp     [esi+8],ebp
  1812.         jne     check_next_language_id
  1813.         add     esi,20
  1814.         mov     eax,esi
  1815.         call    skip_resource_name
  1816.         call    skip_resource_name
  1817.         neg     eax
  1818.         add     eax,esi
  1819.         and     eax,11b
  1820.         add     esi,eax
  1821.       get_language_id:
  1822.         movzx   eax,word [esi+6]
  1823.         cmp     eax,ebx
  1824.         jle     check_next_language_id
  1825.         cmp     eax,edx
  1826.         jge     check_next_language_id
  1827.         mov     edx,eax
  1828.         mov     eax,[esp]
  1829.         mov     [current_offset],eax
  1830.       check_next_language_id:
  1831.         pop     esi
  1832.         mov     eax,[esi+16]
  1833.         lea     esi,[esi+20+eax]
  1834.         jmp     find_language_id
  1835.       language_id_ok:
  1836.         cmp     edx,10000h
  1837.         je      language_id_directory_done
  1838.         mov     ebx,edx
  1839.       make_language_id_entry:
  1840.         mov     eax,[esp]
  1841.         inc     word [eax+14]
  1842.         lea     eax,[edi+8]
  1843.         cmp     eax,[display_buffer]
  1844.         jae     out_of_memory
  1845.         mov     eax,ebx
  1846.         stos    dword [edi]
  1847.         mov     eax,[current_offset]
  1848.         stos    dword [edi]
  1849.         jmp     make_language_id_directory
  1850.       language_id_directory_done:
  1851.         pop     eax
  1852.         mov     esi,ebp
  1853.         pop     ecx
  1854.         add     esi,8
  1855.         dec     cx
  1856.         jnz     make_language_directories
  1857.       language_directories_ok:
  1858.         shr     ecx,16
  1859.         jnz     make_language_directories
  1860.         jmp     update_resource_directories
  1861.       resource_directories_updated:
  1862.         mov     esi,[resource_data]
  1863.         push    edi
  1864.       make_name_strings:
  1865.         add     esi,10h
  1866.         movzx   eax,word [esi-2]
  1867.         movzx   ecx,word [esi-4]
  1868.         add     eax,ecx
  1869.         lea     eax,[esi+eax*8]
  1870.         push    eax
  1871.         or      ecx,ecx
  1872.         jz      string_entries_processed
  1873.       process_string_entries:
  1874.         push    ecx
  1875.         mov     edx,edi
  1876.         sub     edx,[resource_data]
  1877.         bts     edx,31
  1878.         xchg    [esi],edx
  1879.         mov     ebx,edi
  1880.         xor     ax,ax
  1881.         stos    word [edi]
  1882.       copy_string_data:
  1883.         lea     eax,[edi+2]
  1884.         cmp     eax,[display_buffer]
  1885.         jae     out_of_memory
  1886.         mov     ax,[edx]
  1887.         or      ax,ax
  1888.         jz      string_data_copied
  1889.         stos    word [edi]
  1890.         inc     word [ebx]
  1891.         add     edx,2
  1892.         jmp     copy_string_data
  1893.       string_data_copied:
  1894.         add     esi,8
  1895.         pop     ecx
  1896.         loop    process_string_entries
  1897.       string_entries_processed:
  1898.         pop     esi
  1899.         cmp     esi,[esp]
  1900.         jb      make_name_strings
  1901.         mov     eax,edi
  1902.         sub     eax,[resource_data]
  1903.         test    al,11b
  1904.         jz      resource_strings_alignment_ok
  1905.         xor     ax,ax
  1906.         stos    word [edi]
  1907.       resource_strings_alignment_ok:
  1908.         pop     edx
  1909.         pop     ebx                     ; address of language directories
  1910.         mov     ebp,edi
  1911.       update_language_directories:
  1912.         add     ebx,10h
  1913.         movzx   eax,word [ebx-2]
  1914.         movzx   ecx,word [ebx-4]
  1915.         add     ecx,eax
  1916.       make_data_records:
  1917.         push    ecx
  1918.         mov     esi,edi
  1919.         sub     esi,[resource_data]
  1920.         xchg    esi,[ebx+4]
  1921.         lea     eax,[edi+16]
  1922.         cmp     eax,[display_buffer]
  1923.         jae     out_of_memory
  1924.         mov     eax,esi
  1925.         stos    dword [edi]
  1926.         mov     eax,[esi+12]
  1927.         stos    dword [edi]
  1928.         xor     eax,eax
  1929.         stos    dword [edi]
  1930.         stos    dword [edi]
  1931.         pop     ecx
  1932.         add     ebx,8
  1933.         loop    make_data_records
  1934.         cmp     ebx,edx
  1935.         jb      update_language_directories
  1936.         pop     ebx                     ; file handle
  1937.         mov     esi,ebp
  1938.         mov     ebp,edi
  1939.       update_data_records:
  1940.         push    ebp
  1941.         mov     ecx,edi
  1942.         mov     eax,[current_section]
  1943.         sub     ecx,[eax+14h]
  1944.         add     ecx,[eax+0Ch]
  1945.         xchg    ecx,[esi]
  1946.         mov     edx,[ecx]
  1947.         xor     al,al
  1948.         call    lseek
  1949.         mov     edx,edi
  1950.         mov     ecx,[esi+4]
  1951.         add     edi,ecx
  1952.         cmp     edi,[display_buffer]
  1953.         ja      out_of_memory
  1954.         call    read
  1955.         mov     eax,edi
  1956.         sub     eax,[resource_data]
  1957.         and     eax,11b
  1958.         jz      resource_data_alignment_ok
  1959.         mov     ecx,4
  1960.         sub     ecx,eax
  1961.         xor     al,al
  1962.         rep     stos byte [edi]
  1963.       resource_data_alignment_ok:
  1964.         pop     ebp
  1965.         add     esi,16
  1966.         cmp     esi,ebp
  1967.         jb      update_data_records
  1968.         pop     esi
  1969.         call    close
  1970.         mov     eax,edi
  1971.         sub     eax,[resource_data]
  1972.         mov     [resource_size],eax
  1973.       resource_done:
  1974.         ret
  1975. make_pe_fixups:
  1976.         push    esi
  1977.         mov     ecx,[number_of_relocations]
  1978.         jecxz   fixups_done
  1979.         mov     esi,[free_additional_memory]
  1980.         mov     eax,ecx
  1981.         shl     eax,2
  1982.         sub     esi,eax
  1983.         mov     [free_additional_memory],esi
  1984.         or      [number_of_relocations],-1
  1985.         xor     edx,edx
  1986.         mov     ebp,edi
  1987.       make_fixups:
  1988.         cmp     [esi],edx
  1989.         jb      store_fixup
  1990.         mov     eax,edi
  1991.         sub     eax,ebp
  1992.         test    eax,11b
  1993.         jz      fixups_block
  1994.         xor     ax,ax
  1995.         stos    word [edi]
  1996.         add     dword [ebx],2
  1997.       fixups_block:
  1998.         mov     eax,edx
  1999.         add     edx,1000h
  2000.         cmp     [esi],edx
  2001.         jae     fixups_block
  2002.         stos    dword [edi]
  2003.         mov     ebx,edi
  2004.         mov     eax,8
  2005.         stos    dword [edi]
  2006.       store_fixup:
  2007.         add     dword [ebx],2
  2008.         mov     eax,[esi]
  2009.         and     ax,0FFFh
  2010.         test    [format_flags],8
  2011.         jnz     fixup_64bit
  2012.         or      ax,3000h
  2013.         jmp     fixup_ok
  2014.       fixup_64bit:
  2015.         or      ax,0A000h
  2016.       fixup_ok:
  2017.         stos    word [edi]
  2018.         add     esi,4
  2019.         loop    make_fixups
  2020.       fixups_done:
  2021.         pop     esi
  2022.         ret
  2023. close_pe:
  2024.         call    close_pe_section
  2025.         mov     edx,[code_start]
  2026.         mov     [edx+50h],eax
  2027.         call    make_timestamp
  2028.         mov     edx,[code_start]
  2029.         mov     [edx+8],eax
  2030.         mov     eax,[number_of_relocations]
  2031.         cmp     eax,0
  2032.         jle     pe_flags_ok
  2033.         or      word [edx+16h],1
  2034.         shl     eax,2
  2035.         sub     [free_additional_memory],eax
  2036.       pe_flags_ok:
  2037.         mov     eax,[number_of_sections]
  2038.         mov     [edx+6],ax
  2039.         imul    eax,28h
  2040.         movzx   ecx,word [edx+14h]
  2041.         lea     eax,[eax+18h+ecx]
  2042.         add     eax,[stub_size]
  2043.         mov     ecx,[edx+3Ch]
  2044.         dec     ecx
  2045.         add     eax,ecx
  2046.         not     ecx
  2047.         and     eax,ecx
  2048.         cmp     eax,[edx+54h]
  2049.         je      pe_sections_ok
  2050.         or      [next_pass_needed],-1
  2051.       pe_sections_ok:
  2052.         xor     ecx,ecx
  2053.         add     edx,78h
  2054.         test    [format_flags],8
  2055.         jz      process_directories
  2056.         add     edx,10h
  2057.       process_directories:
  2058.         mov     eax,[edx+ecx*8]
  2059.         or      eax,eax
  2060.         jz      directory_ok
  2061.         cmp     dword [edx+ecx*8+4],-1
  2062.         jne     directory_ok
  2063.       section_data:
  2064.         mov     ebx,[edx+ecx*8]
  2065.         mov     eax,[ebx+0Ch]
  2066.         mov     [edx+ecx*8],eax         ; directory rva
  2067.         mov     eax,[ebx+8]
  2068.         mov     [edx+ecx*8+4],eax       ; directory size
  2069.       directory_ok:
  2070.         inc     cl
  2071.         cmp     cl,10h
  2072.         jb      process_directories
  2073.         mov     ebx,[code_start]
  2074.         sub     ebx,[stub_size]
  2075.         mov     ecx,edi
  2076.         sub     ecx,ebx
  2077.         mov     ebp,ecx
  2078.         shr     ecx,1
  2079.         xor     eax,eax
  2080.         cdq
  2081.       calculate_checksum:
  2082.         mov     dx,[ebx]
  2083.         add     eax,edx
  2084.         mov     dx,ax
  2085.         shr     eax,16
  2086.         add     eax,edx
  2087.         add     ebx,2
  2088.         loop    calculate_checksum
  2089.         add     eax,ebp
  2090.         mov     ebx,[code_start]
  2091.         mov     [ebx+58h],eax
  2092.         ret
  2093.  
  2094. format_coff:
  2095.         mov     eax,[additional_memory]
  2096.         mov     [symbols_stream],eax
  2097.         mov     ebx,eax
  2098.         add     eax,18h
  2099.         cmp     eax,[structures_buffer]
  2100.         jae     out_of_memory
  2101.         mov     [free_additional_memory],eax
  2102.         xor     eax,eax
  2103.         mov     [ebx],al
  2104.         mov     [ebx+4],eax
  2105.         mov     [ebx+8],edi
  2106.         mov     al,4
  2107.         mov     [ebx+10h],eax
  2108.         mov     al,60h
  2109.         bt      [format_flags],0
  2110.         jnc     flat_section_flags_ok
  2111.         or      eax,0E0000000h
  2112.       flat_section_flags_ok:
  2113.         mov     dword [ebx+14h],eax
  2114.         mov     [current_section],ebx
  2115.         mov     [number_of_sections],0
  2116.         mov     dword [org_origin],edi
  2117.         mov     dword [org_origin+4],0
  2118.         mov     [org_registers],0
  2119.         mov     [org_start],edi
  2120.         mov     [org_symbol],ebx
  2121.         mov     [labels_type],2
  2122.         mov     [code_type],32
  2123.         test    [format_flags],8
  2124.         jz      instruction_assembled
  2125.         mov     [labels_type],4
  2126.         mov     [code_type],64
  2127.         jmp     instruction_assembled
  2128. coff_section:
  2129.         call    close_coff_section
  2130.         mov     ebx,[free_additional_memory]
  2131.         lea     eax,[ebx+18h]
  2132.         cmp     eax,[structures_buffer]
  2133.         jae     out_of_memory
  2134.         mov     [free_additional_memory],eax
  2135.         mov     [current_section],ebx
  2136.         inc     [number_of_sections]
  2137.         xor     eax,eax
  2138.         mov     [ebx],al
  2139.         mov     [ebx+8],edi
  2140.         mov     dword [org_origin],edi
  2141.         mov     dword [org_origin+4],0
  2142.         mov     [org_registers],0
  2143.         mov     [org_start],edi
  2144.         mov     [org_symbol],ebx
  2145.         mov     [labels_type],2
  2146.         test    [format_flags],8
  2147.         jz      coff_labels_type_ok
  2148.         mov     [labels_type],4
  2149.       coff_labels_type_ok:
  2150.         mov     [ebx+10h],eax
  2151.         mov     [ebx+14h],eax
  2152.         lods    word [esi]
  2153.         cmp     ax,'('
  2154.         jne     invalid_argument
  2155.         mov     [ebx+4],esi
  2156.         mov     ecx,[esi]
  2157.         lea     esi,[esi+4+ecx+1]
  2158.         cmp     ecx,8
  2159.         ja      name_too_long
  2160.       coff_section_flags:
  2161.         cmp     byte [esi],1Ch
  2162.         je      coff_section_alignment
  2163.         cmp     byte [esi],19h
  2164.         jne     coff_section_settings_ok
  2165.         inc     esi
  2166.         lods    byte [esi]
  2167.         bt      [format_flags],0
  2168.         jc      coff_section_flag_ok
  2169.         cmp     al,7
  2170.         ja      invalid_argument
  2171.       coff_section_flag_ok:
  2172.         mov     cl,al
  2173.         mov     eax,1
  2174.         shl     eax,cl
  2175.         test    dword [ebx+14h],eax
  2176.         jnz     setting_already_specified
  2177.         or      dword [ebx+14h],eax
  2178.         jmp     coff_section_flags
  2179.       coff_section_alignment:
  2180.         bt      [format_flags],0
  2181.         jnc     invalid_argument
  2182.         inc     esi
  2183.         lods    byte [esi]
  2184.         or      al,al
  2185.         jnz     invalid_argument
  2186.         lods    byte [esi]
  2187.         cmp     al,'('
  2188.         jne     invalid_argument
  2189.         cmp     byte [esi],'.'
  2190.         je      invalid_value
  2191.         push    ebx
  2192.         call    get_dword_value
  2193.         pop     ebx
  2194.         cmp     [value_type],0
  2195.         jne     invalid_use_of_symbol
  2196.         mov     edx,eax
  2197.         dec     edx
  2198.         test    eax,edx
  2199.         jnz     invalid_value
  2200.         or      eax,eax
  2201.         jz      invalid_value
  2202.         cmp     eax,2000h
  2203.         ja      invalid_value
  2204.         bsf     edx,eax
  2205.         inc     edx
  2206.         shl     edx,20
  2207.         or      [ebx+14h],edx
  2208.         xchg    [ebx+10h],eax
  2209.         or      eax,eax
  2210.         jnz     setting_already_specified
  2211.         jmp     coff_section_flags
  2212.       coff_section_settings_ok:
  2213.         cmp     dword [ebx+10h],0
  2214.         jne     instruction_assembled
  2215.         mov     dword [ebx+10h],4
  2216.         bt      [format_flags],0
  2217.         jnc     instruction_assembled
  2218.         or      dword [ebx+14h],300000h
  2219.         jmp     instruction_assembled
  2220.       close_coff_section:
  2221.         mov     ebx,[current_section]
  2222.         mov     eax,edi
  2223.         mov     edx,[ebx+8]
  2224.         sub     eax,edx
  2225.         mov     [ebx+0Ch],eax
  2226.         xor     eax,eax
  2227.         xchg    [undefined_data_end],eax
  2228.         cmp     eax,edi
  2229.         jne     coff_section_ok
  2230.         cmp     edx,[undefined_data_start]
  2231.         jne     coff_section_ok
  2232.         mov     edi,edx
  2233.         or      byte [ebx+14h],80h
  2234.       coff_section_ok:
  2235.         ret
  2236. mark_coff_relocation:
  2237.         cmp     [value_type],3
  2238.         je      coff_relocation_relative
  2239.         push    ebx eax
  2240.         test    [format_flags],8
  2241.         jnz     coff_64bit_relocation
  2242.         mov     al,6
  2243.         jmp     coff_relocation
  2244.       coff_64bit_relocation:
  2245.         mov     al,1
  2246.         jmp     coff_relocation
  2247.       coff_relocation_relative:
  2248.         push    ebx
  2249.         bt      [format_flags],0
  2250.         jnc     relative_ok
  2251.         mov     ebx,[current_section]
  2252.         mov     ebx,[ebx+8]
  2253.         sub     ebx,edi
  2254.         sub     eax,ebx
  2255.         add     eax,4
  2256.       relative_ok:
  2257.         push    eax
  2258.         mov     al,20
  2259.         test    [format_flags],8
  2260.         jnz     relative_coff_64bit_relocation
  2261.         cmp     [labels_type],2
  2262.         jne     invalid_use_of_symbol
  2263.         jmp     coff_relocation
  2264.       relative_coff_64bit_relocation:
  2265.         mov     al,4
  2266.         cmp     [labels_type],4
  2267.         jne     invalid_use_of_symbol
  2268.       coff_relocation:
  2269.         mov     ebx,[free_additional_memory]
  2270.         add     ebx,0Ch
  2271.         cmp     ebx,[structures_buffer]
  2272.         jae     out_of_memory
  2273.         mov     [free_additional_memory],ebx
  2274.         mov     byte [ebx-0Ch],al
  2275.         mov     eax,[current_section]
  2276.         mov     eax,[eax+8]
  2277.         neg     eax
  2278.         add     eax,edi
  2279.         mov     [ebx-0Ch+4],eax
  2280.         mov     eax,[symbol_identifier]
  2281.         mov     [ebx-0Ch+8],eax
  2282.         pop     eax ebx
  2283.         ret
  2284. close_coff:
  2285.         call    close_coff_section
  2286.         cmp     [next_pass_needed],0
  2287.         je      coff_closed
  2288.         mov     eax,[symbols_stream]
  2289.         mov     [free_additional_memory],eax
  2290.       coff_closed:
  2291.         ret
  2292. coff_formatter:
  2293.         sub     edi,[code_start]
  2294.         mov     [code_size],edi
  2295.         call    prepare_default_section
  2296.         mov     edi,[free_additional_memory]
  2297.         mov     ebx,edi
  2298.         mov     ecx,28h shr 2
  2299.         imul    ecx,[number_of_sections]
  2300.         add     ecx,14h shr 2
  2301.         lea     eax,[edi+ecx*4]
  2302.         cmp     eax,[structures_buffer]
  2303.         jae     out_of_memory
  2304.         xor     eax,eax
  2305.         rep     stos dword [edi]
  2306.         mov     word [ebx],14Ch
  2307.         test    [format_flags],8
  2308.         jz      coff_magic_ok
  2309.         mov     word [ebx],8664h
  2310.       coff_magic_ok:
  2311.         mov     word [ebx+12h],104h
  2312.         bt      [format_flags],0
  2313.         jnc     coff_flags_ok
  2314.         or      byte [ebx+12h],80h
  2315.       coff_flags_ok:
  2316.         push    ebx
  2317.         call    make_timestamp
  2318.         pop     ebx
  2319.         mov     [ebx+4],eax
  2320.         mov     eax,[number_of_sections]
  2321.         mov     [ebx+2],ax
  2322.         mov     esi,[symbols_stream]
  2323.         xor     ecx,ecx
  2324.       enumerate_symbols:
  2325.         cmp     esi,[free_additional_memory]
  2326.         je      symbols_enumerated
  2327.         mov     dl,[esi]
  2328.         or      dl,dl
  2329.         jz      enumerate_section
  2330.         cmp     dl,80h
  2331.         je      enumerate_public
  2332.         ja      enumerate_extrn
  2333.         add     esi,0Ch
  2334.         jmp     enumerate_symbols
  2335.       enumerate_section:
  2336.         mov     edx,ecx
  2337.         shl     edx,8
  2338.         mov     [esi],edx
  2339.         inc     ecx
  2340.         add     esi,18h
  2341.         jmp     enumerate_symbols
  2342.       enumerate_public:
  2343.         mov     edx,eax
  2344.         shl     edx,8
  2345.         mov     dl,80h
  2346.         mov     [esi],edx
  2347.         mov     edx,[esi+8]
  2348.         add     esi,10h
  2349.         inc     eax
  2350.         cmp     byte [edx+11],2
  2351.         jne     enumerate_symbols
  2352.         mov     edx,[edx+20]
  2353.         cmp     byte [edx],81h
  2354.         jne     enumerate_symbols
  2355.         inc     eax
  2356.         jmp     enumerate_symbols
  2357.       enumerate_extrn:
  2358.         mov     edx,eax
  2359.         shl     edx,8
  2360.         mov     dl,81h
  2361.         mov     [esi],edx
  2362.         add     esi,0Ch
  2363.         inc     eax
  2364.         jmp     enumerate_symbols
  2365.       prepare_default_section:
  2366.         mov     ebx,[symbols_stream]
  2367.         cmp     dword [ebx+0Ch],0
  2368.         jne     default_section_ok
  2369.         cmp     [number_of_sections],0
  2370.         je      default_section_ok
  2371.         mov     edx,ebx
  2372.       find_references_to_default_section:
  2373.         cmp     ebx,[free_additional_memory]
  2374.         jne     check_reference
  2375.         add     [symbols_stream],18h
  2376.         ret
  2377.       check_reference:
  2378.         mov     al,[ebx]
  2379.         or      al,al
  2380.         jz      skip_other_section
  2381.         cmp     al,80h
  2382.         je      check_public_reference
  2383.         ja      next_reference
  2384.         cmp     edx,[ebx+8]
  2385.         je      default_section_ok
  2386.       next_reference:
  2387.         add     ebx,0Ch
  2388.         jmp     find_references_to_default_section
  2389.       check_public_reference:
  2390.         mov     eax,[ebx+8]
  2391.         add     ebx,10h
  2392.         test    byte [eax+8],1
  2393.         jz      find_references_to_default_section
  2394.         mov     cx,[current_pass]
  2395.         cmp     cx,[eax+16]
  2396.         jne     find_references_to_default_section
  2397.         cmp     edx,[eax+20]
  2398.         je      default_section_ok
  2399.         jmp     find_references_to_default_section
  2400.       skip_other_section:
  2401.         add     ebx,18h
  2402.         jmp     find_references_to_default_section
  2403.       default_section_ok:
  2404.         inc     [number_of_sections]
  2405.         ret
  2406.       symbols_enumerated:
  2407.         mov     [ebx+0Ch],eax
  2408.         mov     ebp,edi
  2409.         sub     ebp,ebx
  2410.         push    ebp
  2411.         lea     edi,[ebx+14h]
  2412.         mov     esi,[symbols_stream]
  2413.       find_section:
  2414.         cmp     esi,[free_additional_memory]
  2415.         je      sections_finished
  2416.         mov     al,[esi]
  2417.         or      al,al
  2418.         jz      section_found
  2419.         add     esi,0Ch
  2420.         cmp     al,80h
  2421.         jne     find_section
  2422.         add     esi,4
  2423.         jmp     find_section
  2424.       section_found:
  2425.         push    esi edi
  2426.         mov     esi,[esi+4]
  2427.         or      esi,esi
  2428.         jz      default_section
  2429.         mov     ecx,[esi]
  2430.         add     esi,4
  2431.         rep     movs byte [edi],[esi]
  2432.         jmp     section_name_ok
  2433.       default_section:
  2434.         mov     al,'.'
  2435.         stos    byte [edi]
  2436.         mov     eax,'flat'
  2437.         stos    dword [edi]
  2438.       section_name_ok:
  2439.         pop     edi esi
  2440.         mov     eax,[esi+0Ch]
  2441.         mov     [edi+10h],eax
  2442.         mov     eax,[esi+14h]
  2443.         mov     [edi+24h],eax
  2444.         test    al,80h
  2445.         jnz     section_ptr_ok
  2446.         mov     eax,[esi+8]
  2447.         sub     eax,[code_start]
  2448.         add     eax,ebp
  2449.         mov     [edi+14h],eax
  2450.       section_ptr_ok:
  2451.         mov     ebx,[code_start]
  2452.         mov     edx,[code_size]
  2453.         add     ebx,edx
  2454.         add     edx,ebp
  2455.         xor     ecx,ecx
  2456.         add     esi,18h
  2457.       find_relocations:
  2458.         cmp     esi,[free_additional_memory]
  2459.         je      section_relocations_done
  2460.         mov     al,[esi]
  2461.         or      al,al
  2462.         jz      section_relocations_done
  2463.         cmp     al,80h
  2464.         jb      add_relocation
  2465.         ja      next_relocation
  2466.         add     esi,10h
  2467.         jmp     find_relocations
  2468.       add_relocation:
  2469.         lea     eax,[ebx+0Ah]
  2470.         cmp     eax,[display_buffer]
  2471.         ja      out_of_memory
  2472.         mov     eax,[esi+4]
  2473.         mov     [ebx],eax
  2474.         mov     eax,[esi+8]
  2475.         mov     eax,[eax]
  2476.         shr     eax,8
  2477.         mov     [ebx+4],eax
  2478.         movzx   ax,byte [esi]
  2479.         mov     [ebx+8],ax
  2480.         add     ebx,0Ah
  2481.         inc     ecx
  2482.       next_relocation:
  2483.         add     esi,0Ch
  2484.         jmp     find_relocations
  2485.       section_relocations_done:
  2486.         cmp     ecx,10000h
  2487.         jb      section_relocations_count_16bit
  2488.         bt      [format_flags],0
  2489.         jnc     format_limitations_exceeded
  2490.         mov     word [edi+20h],0FFFFh
  2491.         or      dword [edi+24h],1000000h
  2492.         mov     [edi+18h],edx
  2493.         push    esi edi
  2494.         push    ecx
  2495.         lea     esi,[ebx-1]
  2496.         add     ebx,0Ah
  2497.         lea     edi,[ebx-1]
  2498.         imul    ecx,0Ah
  2499.         std
  2500.         rep     movs byte [edi],[esi]
  2501.         cld
  2502.         pop     ecx
  2503.         inc     esi
  2504.         inc     ecx
  2505.         mov     [esi],ecx
  2506.         xor     eax,eax
  2507.         mov     [esi+4],eax
  2508.         mov     [esi+8],ax
  2509.         pop     edi esi
  2510.         jmp     section_relocations_ok
  2511.       section_relocations_count_16bit:
  2512.         mov     [edi+20h],cx
  2513.         jcxz    section_relocations_ok
  2514.         mov     [edi+18h],edx
  2515.       section_relocations_ok:
  2516.         sub     ebx,[code_start]
  2517.         mov     [code_size],ebx
  2518.         add     edi,28h
  2519.         jmp     find_section
  2520.       sections_finished:
  2521.         mov     edx,[free_additional_memory]
  2522.         mov     ebx,[code_size]
  2523.         add     ebp,ebx
  2524.         mov     [edx+8],ebp
  2525.         add     ebx,[code_start]
  2526.         mov     edi,ebx
  2527.         mov     ecx,[edx+0Ch]
  2528.         imul    ecx,12h shr 1
  2529.         xor     eax,eax
  2530.         shr     ecx,1
  2531.         jnc     zero_symbols_table
  2532.         stos    word [edi]
  2533.       zero_symbols_table:
  2534.         rep     stos dword [edi]
  2535.         mov     edx,edi
  2536.         stos    dword [edi]
  2537.         mov     esi,[symbols_stream]
  2538.       make_section_symbols:
  2539.         cmp     esi,[free_additional_memory]
  2540.         je      section_symbols_ok
  2541.         mov     al,[esi]
  2542.         or      al,al
  2543.         jz      add_section_symbol
  2544.         add     esi,0Ch
  2545.         cmp     al,80h
  2546.         jne     make_section_symbols
  2547.         add     esi,4
  2548.         jmp     make_section_symbols
  2549.       add_section_symbol:
  2550.         call    store_symbol_name
  2551.         mov     eax,[esi]
  2552.         shr     eax,8
  2553.         inc     eax
  2554.         mov     [ebx+0Ch],ax
  2555.         mov     byte [ebx+10h],3
  2556.         add     esi,18h
  2557.         add     ebx,12h
  2558.         jmp     make_section_symbols
  2559.       section_symbols_ok:
  2560.         mov     esi,[symbols_stream]
  2561.       make_symbols_table:
  2562.         cmp     esi,[free_additional_memory]
  2563.         je      symbols_table_ok
  2564.         mov     al,[esi]
  2565.         cmp     al,80h
  2566.         je      add_public_symbol
  2567.         ja      add_extrn_symbol
  2568.         add     esi,0Ch
  2569.         or      al,al
  2570.         jnz     make_symbols_table
  2571.         add     esi,0Ch
  2572.         jmp     make_symbols_table
  2573.       add_extrn_symbol:
  2574.         call    store_symbol_name
  2575.         mov     byte [ebx+10h],2
  2576.         add     esi,0Ch
  2577.         add     ebx,12h
  2578.         jmp     make_symbols_table
  2579.       add_public_symbol:
  2580.         call    store_symbol_name
  2581.         mov     eax,[esi+0Ch]
  2582.         mov     [current_line],eax
  2583.         mov     eax,[esi+8]
  2584.         test    byte [eax+8],1
  2585.         jz      undefined_symbol
  2586.         mov     cx,[current_pass]
  2587.         cmp     cx,[eax+16]
  2588.         jne     undefined_symbol
  2589.         mov     cl,[eax+11]
  2590.         or      cl,cl
  2591.         jz      public_constant
  2592.         test    [format_flags],8
  2593.         jnz     check_64bit_public_symbol
  2594.         cmp     cl,2
  2595.         je      public_symbol_type_ok
  2596.         jmp     invalid_use_of_symbol
  2597.       check_64bit_public_symbol:
  2598.         cmp     cl,4
  2599.         jne     invalid_use_of_symbol
  2600.       public_symbol_type_ok:
  2601.         mov     ecx,[eax+20]
  2602.         mov     ecx,[ecx]
  2603.         cmp     cl,81h
  2604.         je      alias_symbol
  2605.         or      cl,cl
  2606.         jnz     invalid_use_of_symbol
  2607.         shr     ecx,8
  2608.         inc     cx
  2609.         mov     [ebx+0Ch],cx
  2610.       public_symbol_section_ok:
  2611.         cmp     dword [eax+4],0
  2612.         je      store_public_symbol
  2613.         cmp     dword [eax+4],-1
  2614.         jne     value_out_of_range
  2615.         bt      dword [eax],31
  2616.         jnc     value_out_of_range
  2617.       store_public_symbol:
  2618.         mov     eax,[eax]
  2619.         mov     [ebx+8],eax
  2620.         mov     byte [ebx+10h],2
  2621.         add     esi,10h
  2622.         add     ebx,12h
  2623.         jmp     make_symbols_table
  2624.       alias_symbol:
  2625.         bt      [format_flags],0
  2626.         jnc     invalid_use_of_symbol
  2627.         mov     ecx,[eax]
  2628.         or      ecx,[eax+4]
  2629.         jnz     invalid_use_of_symbol
  2630.         mov     byte [ebx+10h],69h
  2631.         mov     byte [ebx+11h],1
  2632.         add     ebx,12h
  2633.         mov     ecx,[eax+20]
  2634.         mov     ecx,[ecx]
  2635.         shr     ecx,8
  2636.         mov     [ebx],ecx
  2637.         mov     byte [ebx+4],3
  2638.         add     esi,10h
  2639.         add     ebx,12h
  2640.         jmp     make_symbols_table
  2641.       public_constant:
  2642.         mov     word [ebx+0Ch],0FFFFh
  2643.         jmp     public_symbol_section_ok
  2644.       symbols_table_ok:
  2645.         mov     eax,edi
  2646.         sub     eax,edx
  2647.         mov     [edx],eax
  2648.         sub     edi,[code_start]
  2649.         mov     [code_size],edi
  2650.         mov     [written_size],0
  2651.         mov     edx,[output_file]
  2652.         call    create
  2653.         jc      write_failed
  2654.         mov     edx,[free_additional_memory]
  2655.         pop     ecx
  2656.         add     [written_size],ecx
  2657.         call    write
  2658.         jc      write_failed
  2659.         jmp     write_output
  2660.       store_symbol_name:
  2661.         push    esi
  2662.         mov     esi,[esi+4]
  2663.         or      esi,esi
  2664.         jz      default_name
  2665.         lods    dword [esi]
  2666.         mov     ecx,eax
  2667.         cmp     ecx,8
  2668.         ja      add_string
  2669.         push    edi
  2670.         mov     edi,ebx
  2671.         rep     movs byte [edi],[esi]
  2672.         pop     edi esi
  2673.         ret
  2674.       default_name:
  2675.         mov     dword [ebx],'.fla'
  2676.         mov     dword [ebx+4],'t'
  2677.         pop     esi
  2678.         ret
  2679.       add_string:
  2680.         mov     eax,edi
  2681.         sub     eax,edx
  2682.         mov     [ebx+4],eax
  2683.         inc     ecx
  2684.         rep     movs byte [edi],[esi]
  2685.         pop     esi
  2686.         ret
  2687.  
  2688. format_elf:
  2689.         test    [format_flags],8
  2690.         jnz     format_elf64
  2691.         mov     edx,edi
  2692.         mov     ecx,34h shr 2
  2693.         lea     eax,[edi+ecx*4]
  2694.         cmp     eax,[display_buffer]
  2695.         jae     out_of_memory
  2696.         xor     eax,eax
  2697.         rep     stos dword [edi]
  2698.         mov     dword [edx],7Fh + 'ELF' shl 8
  2699.         mov     al,1
  2700.         mov     [edx+4],al
  2701.         mov     [edx+5],al
  2702.         mov     [edx+6],al
  2703.         mov     [edx+14h],al
  2704.         mov     byte [edx+12h],3
  2705.         mov     byte [edx+28h],34h
  2706.         mov     byte [edx+2Eh],28h
  2707.         mov     [code_type],32
  2708.         cmp     word [esi],1D19h
  2709.         je      format_elf_exe
  2710.         mov     [labels_type],2
  2711.       elf_header_ok:
  2712.         mov     byte [edx+10h],1
  2713.         mov     eax,[additional_memory]
  2714.         mov     [symbols_stream],eax
  2715.         mov     ebx,eax
  2716.         add     eax,18h
  2717.         cmp     eax,[structures_buffer]
  2718.         jae     out_of_memory
  2719.         mov     [free_additional_memory],eax
  2720.         xor     eax,eax
  2721.         mov     [current_section],ebx
  2722.         mov     [number_of_sections],eax
  2723.         mov     dword [org_origin],edi
  2724.         mov     dword [org_origin+4],eax
  2725.         mov     [org_registers],eax
  2726.         mov     [org_start],edi
  2727.         mov     [org_symbol],ebx
  2728.         mov     [ebx],al
  2729.         mov     [ebx+4],eax
  2730.         mov     [ebx+8],edi
  2731.         mov     al,111b
  2732.         mov     [ebx+14h],eax
  2733.         mov     al,4
  2734.         mov     [ebx+10h],eax
  2735.         test    [format_flags],8
  2736.         jz      instruction_assembled
  2737.         mov     byte [ebx+10h],8
  2738.         jmp     instruction_assembled
  2739.       format_elf64:
  2740.         mov     edx,edi
  2741.         mov     ecx,40h shr 2
  2742.         lea     eax,[edi+ecx*4]
  2743.         cmp     eax,[display_buffer]
  2744.         jae     out_of_memory
  2745.         xor     eax,eax
  2746.         rep     stos dword [edi]
  2747.         mov     dword [edx],7Fh + 'ELF' shl 8
  2748.         mov     al,1
  2749.         mov     [edx+5],al
  2750.         mov     [edx+6],al
  2751.         mov     [edx+14h],al
  2752.         mov     byte [edx+4],2
  2753.         mov     byte [edx+12h],62
  2754.         mov     byte [edx+34h],40h
  2755.         mov     byte [edx+3Ah],40h
  2756.         mov     [code_type],64
  2757.         cmp     word [esi],1D19h
  2758.         je      format_elf64_exe
  2759.         mov     [labels_type],4
  2760.         jmp     elf_header_ok
  2761. elf_section:
  2762.         bt      [format_flags],0
  2763.         jc      elf_exe_section
  2764.         call    close_coff_section
  2765.         mov     ebx,[free_additional_memory]
  2766.         lea     eax,[ebx+18h]
  2767.         cmp     eax,[structures_buffer]
  2768.         jae     out_of_memory
  2769.         mov     [free_additional_memory],eax
  2770.         mov     [current_section],ebx
  2771.         inc     word [number_of_sections]
  2772.         jz      format_limitations_exceeded
  2773.         xor     eax,eax
  2774.         mov     [ebx],al
  2775.         mov     [ebx+8],edi
  2776.         mov     dword [org_origin],edi
  2777.         mov     dword [org_origin+4],0
  2778.         mov     [org_registers],0
  2779.         mov     [org_start],edi
  2780.         mov     [org_symbol],ebx
  2781.         test    [format_flags],8
  2782.         jnz     elf64_labels_type
  2783.         mov     [labels_type],2
  2784.         jmp     elf_labels_type_ok
  2785.       elf64_labels_type:
  2786.         mov     [labels_type],4
  2787.       elf_labels_type_ok:
  2788.         mov     [ebx+10h],eax
  2789.         mov     al,10b
  2790.         mov     [ebx+14h],eax
  2791.         lods    word [esi]
  2792.         cmp     ax,'('
  2793.         jne     invalid_argument
  2794.         mov     [ebx+4],esi
  2795.         mov     ecx,[esi]
  2796.         lea     esi,[esi+4+ecx+1]
  2797.       elf_section_flags:
  2798.         cmp     byte [esi],1Ch
  2799.         je      elf_section_alignment
  2800.         cmp     byte [esi],19h
  2801.         jne     elf_section_settings_ok
  2802.         inc     esi
  2803.         lods    byte [esi]
  2804.         sub     al,28
  2805.         xor     al,11b
  2806.         test    al,not 10b
  2807.         jnz     invalid_argument
  2808.         mov     cl,al
  2809.         mov     al,1
  2810.         shl     al,cl
  2811.         test    byte [ebx+14h],al
  2812.         jnz     setting_already_specified
  2813.         or      byte [ebx+14h],al
  2814.         jmp     elf_section_flags
  2815.       elf_section_alignment:
  2816.         inc     esi
  2817.         lods    byte [esi]
  2818.         or      al,al
  2819.         jnz     invalid_argument
  2820.         lods    byte [esi]
  2821.         cmp     al,'('
  2822.         jne     invalid_argument
  2823.         cmp     byte [esi],'.'
  2824.         je      invalid_value
  2825.         push    ebx
  2826.         call    get_dword_value
  2827.         pop     ebx
  2828.         cmp     [value_type],0
  2829.         jne     invalid_use_of_symbol
  2830.         mov     edx,eax
  2831.         dec     edx
  2832.         test    eax,edx
  2833.         jnz     invalid_value
  2834.         or      eax,eax
  2835.         jz      invalid_value
  2836.         xchg    [ebx+10h],eax
  2837.         or      eax,eax
  2838.         jnz     setting_already_specified
  2839.         jmp     elf_section_flags
  2840.       elf_section_settings_ok:
  2841.         cmp     dword [ebx+10h],0
  2842.         jne     instruction_assembled
  2843.         mov     dword [ebx+10h],4
  2844.         test    [format_flags],8
  2845.         jz      instruction_assembled
  2846.         mov     byte [ebx+10h],8
  2847.         jmp     instruction_assembled
  2848. mark_elf_relocation:
  2849.         cmp     [value_type],3
  2850.         je      elf_relocation_relative
  2851.         push    ebx eax
  2852.         mov     al,1
  2853.         jmp     coff_relocation
  2854.       elf_relocation_relative:
  2855.         cmp     [labels_type],0
  2856.         je      invalid_use_of_symbol
  2857.         push    ebx
  2858.         mov     ebx,[current_section]
  2859.         mov     ebx,[ebx+8]
  2860.         sub     ebx,edi
  2861.         sub     eax,ebx
  2862.         push    eax
  2863.         mov     al,2
  2864.         jmp     coff_relocation
  2865. close_elf:
  2866.         bt      [format_flags],0
  2867.         jc      close_elf_exe
  2868.         call    close_coff_section
  2869.         cmp     [next_pass_needed],0
  2870.         je      elf_closed
  2871.         mov     eax,[symbols_stream]
  2872.         mov     [free_additional_memory],eax
  2873.       elf_closed:
  2874.         ret
  2875. elf_formatter:
  2876.         push    edi
  2877.         call    prepare_default_section
  2878.         mov     esi,[symbols_stream]
  2879.         mov     edi,[free_additional_memory]
  2880.         xor     eax,eax
  2881.         mov     ecx,4
  2882.         rep     stos dword [edi]
  2883.         test    [format_flags],8
  2884.         jz      find_first_section
  2885.         mov     ecx,2
  2886.         rep     stos dword [edi]
  2887.       find_first_section:
  2888.         mov     al,[esi]
  2889.         or      al,al
  2890.         jz      first_section_found
  2891.         cmp     al,80h
  2892.         jne     skip_other_symbol
  2893.         add     esi,4
  2894.       skip_other_symbol:
  2895.         add     esi,0Ch
  2896.         jmp     find_first_section
  2897.       first_section_found:
  2898.         mov     ebx,esi
  2899.         mov     ebp,esi
  2900.         add     esi,18h
  2901.         xor     ecx,ecx
  2902.         xor     edx,edx
  2903.       find_next_section:
  2904.         cmp     esi,[free_additional_memory]
  2905.         je      make_section_symbol
  2906.         mov     al,[esi]
  2907.         or      al,al
  2908.         jz      make_section_symbol
  2909.         cmp     al,80h
  2910.         je      skip_public
  2911.         ja      skip_extrn
  2912.         or      byte [ebx+14h],40h
  2913.       skip_extrn:
  2914.         add     esi,0Ch
  2915.         jmp     find_next_section
  2916.       skip_public:
  2917.         add     esi,10h
  2918.         jmp     find_next_section
  2919.       make_section_symbol:
  2920.         mov     eax,edi
  2921.         xchg    eax,[ebx+4]
  2922.         stos    dword [edi]
  2923.         test    [format_flags],8
  2924.         jnz     elf64_section_symbol
  2925.         xor     eax,eax
  2926.         stos    dword [edi]
  2927.         stos    dword [edi]
  2928.         call    store_section_index
  2929.         jmp     section_symbol_ok
  2930.       store_section_index:
  2931.         inc     ecx
  2932.         mov     eax,ecx
  2933.         shl     eax,8
  2934.         mov     [ebx],eax
  2935.         inc     dx
  2936.         jz      format_limitations_exceeded
  2937.         mov     eax,edx
  2938.         shl     eax,16
  2939.         mov     al,3
  2940.         test    byte [ebx+14h],40h
  2941.         jz      section_index_ok
  2942.         or      ah,-1
  2943.         inc     dx
  2944.         jz      format_limitations_exceeded
  2945.       section_index_ok:
  2946.         stos    dword [edi]
  2947.         ret
  2948.       elf64_section_symbol:
  2949.         call    store_section_index
  2950.         xor     eax,eax
  2951.         stos    dword [edi]
  2952.         stos    dword [edi]
  2953.         stos    dword [edi]
  2954.         stos    dword [edi]
  2955.       section_symbol_ok:
  2956.         mov     ebx,esi
  2957.         add     esi,18h
  2958.         cmp     ebx,[free_additional_memory]
  2959.         jne     find_next_section
  2960.         inc     dx
  2961.         jz      format_limitations_exceeded
  2962.         mov     [current_section],edx
  2963.         mov     esi,[symbols_stream]
  2964.       find_other_symbols:
  2965.         cmp     esi,[free_additional_memory]
  2966.         je      elf_symbol_table_ok
  2967.         mov     al,[esi]
  2968.         or      al,al
  2969.         jz      skip_section
  2970.         cmp     al,80h
  2971.         je      make_public_symbol
  2972.         ja      make_extrn_symbol
  2973.         add     esi,0Ch
  2974.         jmp     find_other_symbols
  2975.       skip_section:
  2976.         add     esi,18h
  2977.         jmp     find_other_symbols
  2978.       make_public_symbol:
  2979.         mov     eax,[esi+0Ch]
  2980.         mov     [current_line],eax
  2981.         mov     ebx,[esi+8]
  2982.         test    byte [ebx+8],1
  2983.         jz      undefined_symbol
  2984.         mov     ax,[current_pass]
  2985.         cmp     ax,[ebx+16]
  2986.         jne     undefined_symbol
  2987.         mov     dl,[ebx+11]
  2988.         or      dl,dl
  2989.         jz      public_absolute
  2990.         mov     eax,[ebx+20]
  2991.         cmp     byte [eax],0
  2992.         jne     invalid_use_of_symbol
  2993.         mov     eax,[eax+4]
  2994.         test    [format_flags],8
  2995.         jnz     elf64_public
  2996.         cmp     dl,2
  2997.         jne     invalid_use_of_symbol
  2998.         mov     dx,[eax+0Eh]
  2999.         jmp     section_for_public_ok
  3000.       elf64_public:
  3001.         cmp     dl,4
  3002.         jne     invalid_use_of_symbol
  3003.         mov     dx,[eax+6]
  3004.         jmp     section_for_public_ok
  3005.       public_absolute:
  3006.         mov     dx,0FFF1h
  3007.       section_for_public_ok:
  3008.         mov     eax,[esi+4]
  3009.         stos    dword [edi]
  3010.         test    [format_flags],8
  3011.         jnz     elf64_public_symbol
  3012.         call    get_public_value
  3013.         stos    dword [edi]
  3014.         xor     eax,eax
  3015.         mov     al,[ebx+10]
  3016.         stos    dword [edi]
  3017.         mov     eax,edx
  3018.         shl     eax,16
  3019.         mov     al,10h
  3020.         stos    dword [edi]
  3021.         jmp     public_symbol_ok
  3022.       elf64_public_symbol:
  3023.         mov     eax,edx
  3024.         shl     eax,16
  3025.         mov     al,10h
  3026.         stos    dword [edi]
  3027.         call    get_public_value
  3028.         stos    dword [edi]
  3029.         xor     eax,eax
  3030.         stos    dword [edi]
  3031.         mov     al,[ebx+10]
  3032.         stos    dword [edi]
  3033.         xor     al,al
  3034.         stos    dword [edi]
  3035.       public_symbol_ok:
  3036.         inc     ecx
  3037.         mov     eax,ecx
  3038.         shl     eax,8
  3039.         mov     al,80h
  3040.         mov     [esi],eax
  3041.         add     esi,10h
  3042.         jmp     find_other_symbols
  3043.       get_public_value:
  3044.         mov     eax,[ebx]
  3045.         cmp     dword [ebx+4],0
  3046.         je      public_value_ok
  3047.         cmp     dword [ebx+4],-1
  3048.         jne     value_out_of_range
  3049.         bt      eax,31
  3050.         jnc     value_out_of_range
  3051.       public_value_ok:
  3052.         ret
  3053.       make_extrn_symbol:
  3054.         mov     eax,[esi+4]
  3055.         stos    dword [edi]
  3056.         test    [format_flags],8
  3057.         jnz     elf64_extrn_symbol
  3058.         xor     eax,eax
  3059.         stos    dword [edi]
  3060.         mov     eax,[esi+8]
  3061.         stos    dword [edi]
  3062.         mov     eax,10h
  3063.         stos    dword [edi]
  3064.         jmp     extrn_symbol_ok
  3065.       elf64_extrn_symbol:
  3066.         mov     eax,10h
  3067.         stos    dword [edi]
  3068.         xor     al,al
  3069.         stos    dword [edi]
  3070.         stos    dword [edi]
  3071.         mov     eax,[esi+8]
  3072.         stos    dword [edi]
  3073.         xor     eax,eax
  3074.         stos    dword [edi]
  3075.       extrn_symbol_ok:
  3076.         inc     ecx
  3077.         mov     eax,ecx
  3078.         shl     eax,8
  3079.         mov     al,81h
  3080.         mov     [esi],eax
  3081.         add     esi,0Ch
  3082.         jmp     find_other_symbols
  3083.       elf_symbol_table_ok:
  3084.         mov     edx,edi
  3085.         mov     ebx,[free_additional_memory]
  3086.         xor     al,al
  3087.         stos    byte [edi]
  3088.         add     edi,16
  3089.         mov     [edx+1],edx
  3090.         add     ebx,10h
  3091.         test    [format_flags],8
  3092.         jz      make_string_table
  3093.         add     ebx,8
  3094.       make_string_table:
  3095.         cmp     ebx,edx
  3096.         je      elf_string_table_ok
  3097.         test    [format_flags],8
  3098.         jnz     make_elf64_string
  3099.         cmp     byte [ebx+0Dh],0
  3100.         je      rel_prefix_ok
  3101.         mov     byte [ebx+0Dh],0
  3102.         mov     eax,'.rel'
  3103.         stos    dword [edi]
  3104.       rel_prefix_ok:
  3105.         mov     esi,edi
  3106.         sub     esi,edx
  3107.         xchg    esi,[ebx]
  3108.         add     ebx,10h
  3109.       make_elf_string:
  3110.         or      esi,esi
  3111.         jz      default_string
  3112.         lods    dword [esi]
  3113.         mov     ecx,eax
  3114.         rep     movs byte [edi],[esi]
  3115.         xor     al,al
  3116.         stos    byte [edi]
  3117.         jmp     make_string_table
  3118.       make_elf64_string:
  3119.         cmp     byte [ebx+5],0
  3120.         je      elf64_rel_prefix_ok
  3121.         mov     byte [ebx+5],0
  3122.         mov     eax,'.rel'
  3123.         stos    dword [edi]
  3124.         mov     al,'a'
  3125.         stos    byte [edi]
  3126.       elf64_rel_prefix_ok:
  3127.         mov     esi,edi
  3128.         sub     esi,edx
  3129.         xchg    esi,[ebx]
  3130.         add     ebx,18h
  3131.         jmp     make_elf_string
  3132.       default_string:
  3133.         mov     eax,'.fla'
  3134.         stos    dword [edi]
  3135.         mov     ax,'t'
  3136.         stos    word [edi]
  3137.         jmp     make_string_table
  3138.       elf_string_table_ok:
  3139.         mov     [edx+1+8],edi
  3140.         mov     ebx,[code_start]
  3141.         mov     eax,edi
  3142.         sub     eax,[free_additional_memory]
  3143.         test    [format_flags],8
  3144.         jnz     finish_elf64_header
  3145.         mov     [ebx+20h],eax
  3146.         mov     eax,[current_section]
  3147.         inc     ax
  3148.         jz      format_limitations_exceeded
  3149.         mov     [ebx+32h],ax
  3150.         inc     ax
  3151.         jz      format_limitations_exceeded
  3152.         mov     [ebx+30h],ax
  3153.         jmp     elf_header_finished
  3154.       finish_elf64_header:
  3155.         mov     [ebx+28h],eax
  3156.         mov     eax,[current_section]
  3157.         inc     ax
  3158.         jz      format_limitations_exceeded
  3159.         mov     [ebx+3Eh],ax
  3160.         inc     ax
  3161.         jz      format_limitations_exceeded
  3162.         mov     [ebx+3Ch],ax
  3163.       elf_header_finished:
  3164.         xor     eax,eax
  3165.         mov     ecx,10
  3166.         rep     stos dword [edi]
  3167.         test    [format_flags],8
  3168.         jz      elf_null_section_ok
  3169.         mov     ecx,6
  3170.         rep     stos dword [edi]
  3171.       elf_null_section_ok:
  3172.         mov     esi,ebp
  3173.         xor     ecx,ecx
  3174.       make_section_entry:
  3175.         mov     ebx,edi
  3176.         mov     eax,[esi+4]
  3177.         mov     eax,[eax]
  3178.         stos    dword [edi]
  3179.         mov     eax,1
  3180.         cmp     dword [esi+0Ch],0
  3181.         je      bss_section
  3182.         test    byte [esi+14h],80h
  3183.         jz      section_type_ok
  3184.       bss_section:
  3185.         mov     al,8
  3186.       section_type_ok:
  3187.         stos    dword [edi]
  3188.         mov     eax,[esi+14h]
  3189.         and     al,3Fh
  3190.         call    store_elf_machine_word
  3191.         xor     eax,eax
  3192.         call    store_elf_machine_word
  3193.         mov     eax,[esi+8]
  3194.         mov     [image_base],eax
  3195.         sub     eax,[code_start]
  3196.         call    store_elf_machine_word
  3197.         mov     eax,[esi+0Ch]
  3198.         call    store_elf_machine_word
  3199.         xor     eax,eax
  3200.         stos    dword [edi]
  3201.         stos    dword [edi]
  3202.         mov     eax,[esi+10h]
  3203.         call    store_elf_machine_word
  3204.         xor     eax,eax
  3205.         call    store_elf_machine_word
  3206.         inc     ecx
  3207.         add     esi,18h
  3208.         xchg    edi,[esp]
  3209.         mov     ebp,edi
  3210.       convert_relocations:
  3211.         cmp     esi,[free_additional_memory]
  3212.         je      relocations_converted
  3213.         mov     al,[esi]
  3214.         or      al,al
  3215.         jz      relocations_converted
  3216.         cmp     al,80h
  3217.         jb      make_relocation_entry
  3218.         ja      relocation_entry_ok
  3219.         add     esi,10h
  3220.         jmp     convert_relocations
  3221.       make_relocation_entry:
  3222.         test    [format_flags],8
  3223.         jnz     make_elf64_relocation_entry
  3224.         mov     eax,[esi+4]
  3225.         stos    dword [edi]
  3226.         mov     eax,[esi+8]
  3227.         mov     eax,[eax]
  3228.         mov     al,[esi]
  3229.         stos    dword [edi]
  3230.         jmp     relocation_entry_ok
  3231.       make_elf64_relocation_entry:
  3232.         mov     eax,[esi+4]
  3233.         stos    dword [edi]
  3234.         xor     eax,eax
  3235.         stos    dword [edi]
  3236.         movzx   eax,byte [esi]
  3237.         stos    dword [edi]
  3238.         mov     eax,[esi+8]
  3239.         mov     eax,[eax]
  3240.         shr     eax,8
  3241.         stos    dword [edi]
  3242.         xor     eax,eax
  3243.         stos    dword [edi]
  3244.         stos    dword [edi]
  3245.       relocation_entry_ok:
  3246.         add     esi,0Ch
  3247.         jmp     convert_relocations
  3248.       store_elf_machine_word:
  3249.         stos    dword [edi]
  3250.         test    [format_flags],8
  3251.         jz      elf_machine_word_ok
  3252.         mov     dword [edi],0
  3253.         add     edi,4
  3254.       elf_machine_word_ok:
  3255.         ret
  3256.       relocations_converted:
  3257.         cmp     edi,ebp
  3258.         xchg    edi,[esp]
  3259.         je      rel_section_ok
  3260.         mov     eax,[ebx]
  3261.         sub     eax,4
  3262.         test    [format_flags],8
  3263.         jz      store_relocations_name_offset
  3264.         dec     eax
  3265.       store_relocations_name_offset:
  3266.         stos    dword [edi]
  3267.         test    [format_flags],8
  3268.         jnz     rela_section
  3269.         mov     eax,9
  3270.         jmp     store_relocations_type
  3271.       rela_section:
  3272.         mov     eax,4
  3273.       store_relocations_type:
  3274.         stos    dword [edi]
  3275.         xor     al,al
  3276.         call    store_elf_machine_word
  3277.         call    store_elf_machine_word
  3278.         mov     eax,ebp
  3279.         sub     eax,[code_start]
  3280.         call    store_elf_machine_word
  3281.         mov     eax,[esp]
  3282.         sub     eax,ebp
  3283.         call    store_elf_machine_word
  3284.         mov     eax,[current_section]
  3285.         stos    dword [edi]
  3286.         mov     eax,ecx
  3287.         stos    dword [edi]
  3288.         inc     ecx
  3289.         test    [format_flags],8
  3290.         jnz     finish_elf64_rela_section
  3291.         mov     eax,4
  3292.         stos    dword [edi]
  3293.         mov     al,8
  3294.         stos    dword [edi]
  3295.         jmp     rel_section_ok
  3296.       finish_elf64_rela_section:
  3297.         mov     eax,8
  3298.         stos    dword [edi]
  3299.         xor     al,al
  3300.         stos    dword [edi]
  3301.         mov     al,24
  3302.         stos    dword [edi]
  3303.         xor     al,al
  3304.         stos    dword [edi]
  3305.       rel_section_ok:
  3306.         cmp     esi,[free_additional_memory]
  3307.         jne     make_section_entry
  3308.         pop     eax
  3309.         mov     ebx,[code_start]
  3310.         sub     eax,ebx
  3311.         mov     [code_size],eax
  3312.         mov     ecx,20h
  3313.         test    [format_flags],8
  3314.         jz      adjust_elf_section_headers_offset
  3315.         mov     ecx,28h
  3316.       adjust_elf_section_headers_offset:
  3317.         add     [ebx+ecx],eax
  3318.         mov     eax,1
  3319.         stos    dword [edi]
  3320.         mov     al,2
  3321.         stos    dword [edi]
  3322.         xor     al,al
  3323.         call    store_elf_machine_word
  3324.         call    store_elf_machine_word
  3325.         mov     eax,[code_size]
  3326.         call    store_elf_machine_word
  3327.         mov     eax,[edx+1]
  3328.         sub     eax,[free_additional_memory]
  3329.         call    store_elf_machine_word
  3330.         mov     eax,[current_section]
  3331.         inc     eax
  3332.         stos    dword [edi]
  3333.         mov     eax,[number_of_sections]
  3334.         inc     eax
  3335.         stos    dword [edi]
  3336.         test    [format_flags],8
  3337.         jnz     finish_elf64_sym_section
  3338.         mov     eax,4
  3339.         stos    dword [edi]
  3340.         mov     al,10h
  3341.         stos    dword [edi]
  3342.         jmp     sym_section_ok
  3343.       finish_elf64_sym_section:
  3344.         mov     eax,8
  3345.         stos    dword [edi]
  3346.         xor     al,al
  3347.         stos    dword [edi]
  3348.         mov     al,18h
  3349.         stos    dword [edi]
  3350.         xor     al,al
  3351.         stos    dword [edi]
  3352.       sym_section_ok:
  3353.         mov     al,1+8
  3354.         stos    dword [edi]
  3355.         mov     al,3
  3356.         stos    dword [edi]
  3357.         xor     al,al
  3358.         call    store_elf_machine_word
  3359.         call    store_elf_machine_word
  3360.         mov     eax,[edx+1]
  3361.         sub     eax,[free_additional_memory]
  3362.         add     eax,[code_size]
  3363.         call    store_elf_machine_word
  3364.         mov     eax,[edx+1+8]
  3365.         sub     eax,[edx+1]
  3366.         call    store_elf_machine_word
  3367.         xor     eax,eax
  3368.         stos    dword [edi]
  3369.         stos    dword [edi]
  3370.         mov     al,1
  3371.         call    store_elf_machine_word
  3372.         xor     eax,eax
  3373.         call    store_elf_machine_word
  3374.         mov     eax,'tab'
  3375.         mov     dword [edx+1],'.sym'
  3376.         mov     [edx+1+4],eax
  3377.         mov     dword [edx+1+8],'.str'
  3378.         mov     [edx+1+8+4],eax
  3379.         mov     [written_size],0
  3380.         mov     edx,[output_file]
  3381.         call    create
  3382.         jc      write_failed
  3383.         call    write_code
  3384.         mov     ecx,edi
  3385.         mov     edx,[free_additional_memory]
  3386.         sub     ecx,edx
  3387.         add     [written_size],ecx
  3388.         call    write
  3389.         jc      write_failed
  3390.         jmp     output_written
  3391.  
  3392. format_elf_exe:
  3393.         add     esi,2
  3394.         or      [format_flags],1
  3395.         mov     [image_base],8048000h
  3396.         cmp     byte [esi],80h
  3397.         jne     elf_exe_base_ok
  3398.         lods    word [esi]
  3399.         cmp     ah,'('
  3400.         jne     invalid_argument
  3401.         cmp     byte [esi],'.'
  3402.         je      invalid_value
  3403.         push    edx
  3404.         call    get_dword_value
  3405.         cmp     [value_type],0
  3406.         jne     invalid_use_of_symbol
  3407.         mov     [image_base],eax
  3408.         pop     edx
  3409.       elf_exe_base_ok:
  3410.         mov     byte [edx+10h],2
  3411.         mov     byte [edx+2Ah],20h
  3412.         mov     ebx,edi
  3413.         mov     ecx,20h shr 2
  3414.         cmp     [current_pass],0
  3415.         je      init_elf_exe_sections
  3416.         imul    ecx,[number_of_sections]
  3417.       init_elf_exe_sections:
  3418.         xor     eax,eax
  3419.         rep     stos dword [edi]
  3420.         mov     [number_of_sections],0
  3421.         mov     byte [ebx],1
  3422.         mov     word [ebx+1Ch],1000h
  3423.         mov     byte [ebx+18h],111b
  3424.         mov     eax,edi
  3425.         sub     eax,[code_start]
  3426.         mov     [ebx+4],eax
  3427.         add     eax,[image_base]
  3428.         mov     [ebx+8],eax
  3429.         mov     [ebx+0Ch],eax
  3430.         mov     [edx+18h],eax
  3431.         xor     edx,edx
  3432.         not     eax
  3433.         not     edx
  3434.         add     eax,1
  3435.         adc     edx,0
  3436.         add     eax,edi
  3437.         adc     edx,0
  3438.         mov     dword [org_origin],eax
  3439.         mov     dword [org_origin+4],edx
  3440.         mov     [org_registers],0
  3441.         mov     [org_start],edi
  3442.         mov     [symbols_stream],edi
  3443.         jmp     instruction_assembled
  3444.       format_elf64_exe:
  3445.         add     esi,2
  3446.         or      [format_flags],1
  3447.         mov     [image_base],400000h
  3448.         mov     [image_base_high],0
  3449.         cmp     byte [esi],80h
  3450.         jne     elf64_exe_base_ok
  3451.         lods    word [esi]
  3452.         cmp     ah,'('
  3453.         jne     invalid_argument
  3454.         cmp     byte [esi],'.'
  3455.         je      invalid_value
  3456.         push    edx
  3457.         call    get_qword_value
  3458.         cmp     [value_type],0
  3459.         jne     invalid_use_of_symbol
  3460.         mov     [image_base],eax
  3461.         mov     [image_base_high],edx
  3462.         pop     edx
  3463.       elf64_exe_base_ok:
  3464.         mov     byte [edx+10h],2
  3465.         mov     byte [edx+36h],38h
  3466.         mov     ebx,edi
  3467.         mov     ecx,38h shr 2
  3468.         cmp     [current_pass],0
  3469.         je      init_elf64_exe_sections
  3470.         imul    ecx,[number_of_sections]
  3471.       init_elf64_exe_sections:
  3472.         xor     eax,eax
  3473.         rep     stos dword [edi]
  3474.         mov     [number_of_sections],0
  3475.         mov     byte [ebx],1
  3476.         mov     word [ebx+30h],1000h
  3477.         mov     byte [ebx+4],111b
  3478.         push    edx
  3479.         mov     eax,edi
  3480.         sub     eax,[code_start]
  3481.         mov     [ebx+8],eax
  3482.         xor     edx,edx
  3483.         add     eax,[image_base]
  3484.         adc     edx,[image_base_high]
  3485.         mov     [ebx+10h],eax
  3486.         mov     [ebx+10h+4],edx
  3487.         mov     [ebx+18h],eax
  3488.         mov     [ebx+18h+4],edx
  3489.         pop     ebx
  3490.         mov     [ebx+18h],eax
  3491.         mov     [ebx+18h+4],edx
  3492.         not     eax
  3493.         not     edx
  3494.         add     eax,1
  3495.         adc     edx,0
  3496.         add     eax,edi
  3497.         adc     edx,0
  3498.         mov     dword [org_origin],eax
  3499.         mov     dword [org_origin+4],edx
  3500.         mov     [org_registers],0
  3501.         mov     [org_start],edi
  3502.         mov     [symbols_stream],edi
  3503.         jmp     instruction_assembled
  3504. elf_entry:
  3505.         lods    byte [esi]
  3506.         cmp     al,'('
  3507.         jne     invalid_argument
  3508.         cmp     byte [esi],'.'
  3509.         je      invalid_value
  3510.         test    [format_flags],8
  3511.         jnz     elf64_entry
  3512.         call    get_dword_value
  3513.         cmp     [value_type],0
  3514.         jne     invalid_use_of_symbol
  3515.         mov     edx,[code_start]
  3516.         mov     [edx+18h],eax
  3517.         jmp     instruction_assembled
  3518.       elf64_entry:
  3519.         call    get_qword_value
  3520.         cmp     [value_type],0
  3521.         jne     invalid_use_of_symbol
  3522.         mov     ebx,[code_start]
  3523.         mov     [ebx+18h],eax
  3524.         mov     [ebx+1Ch],edx
  3525.         jmp     instruction_assembled
  3526. elf_exe_section:
  3527.         test    [format_flags],8
  3528.         jnz     elf64_exe_section
  3529.         call    close_elf_exe_section
  3530.         push    eax
  3531.         mov     ebx,[number_of_sections]
  3532.         shl     ebx,5
  3533.         add     ebx,[code_start]
  3534.         add     ebx,34h
  3535.         cmp     ebx,[symbols_stream]
  3536.         jb      new_elf_exe_section
  3537.         mov     ebx,[symbols_stream]
  3538.         sub     ebx,20h
  3539.         push    edi
  3540.         mov     edi,ebx
  3541.         mov     ecx,20h shr 2
  3542.         xor     eax,eax
  3543.         rep     stos dword [edi]
  3544.         pop     edi
  3545.         or      [next_pass_needed],-1
  3546.       new_elf_exe_section:
  3547.         mov     byte [ebx],1
  3548.         mov     word [ebx+1Ch],1000h
  3549.       elf_exe_section_flags:
  3550.         cmp     byte [esi],19h
  3551.         jne     elf_exe_section_flags_ok
  3552.         lods    word [esi]
  3553.         sub     ah,28
  3554.         jbe     invalid_argument
  3555.         cmp     ah,1
  3556.         je      mark_elf_exe_section_flag
  3557.         cmp     ah,3
  3558.         ja      invalid_argument
  3559.         xor     ah,1
  3560.         cmp     ah,2
  3561.         je      mark_elf_exe_section_flag
  3562.         inc     ah
  3563.       mark_elf_exe_section_flag:
  3564.         test    [ebx+18h],ah
  3565.         jnz     setting_already_specified
  3566.         or      [ebx+18h],ah
  3567.         jmp     elf_exe_section_flags
  3568.       elf_exe_section_flags_ok:
  3569.         mov     eax,edi
  3570.         sub     eax,[code_start]
  3571.         mov     [ebx+4],eax
  3572.         pop     edx
  3573.         and     eax,0FFFh
  3574.         add     edx,eax
  3575.         mov     [ebx+8],edx
  3576.         mov     [ebx+0Ch],edx
  3577.         mov     eax,edx
  3578.         xor     edx,edx
  3579.         not     eax
  3580.         not     edx
  3581.         add     eax,1
  3582.         adc     edx,0
  3583.         add     eax,edi
  3584.         adc     edx,0
  3585.         mov     dword [org_origin],eax
  3586.         mov     dword [org_origin+4],edx
  3587.         mov     [org_registers],0
  3588.         mov     [org_start],edi
  3589.         inc     [number_of_sections]
  3590.         jmp     instruction_assembled
  3591.       close_elf_exe_section:
  3592.         cmp     [number_of_sections],0
  3593.         jne     finish_elf_exe_section
  3594.         cmp     edi,[symbols_stream]
  3595.         jne     first_elf_exe_section_ok
  3596.         push    edi
  3597.         mov     edi,[code_start]
  3598.         add     edi,34h
  3599.         mov     ecx,20h shr 2
  3600.         xor     eax,eax
  3601.         rep     stos dword [edi]
  3602.         pop     edi
  3603.         mov     eax,[image_base]
  3604.         ret
  3605.       first_elf_exe_section_ok:
  3606.         inc     [number_of_sections]
  3607.       finish_elf_exe_section:
  3608.         mov     ebx,[number_of_sections]
  3609.         dec     ebx
  3610.         shl     ebx,5
  3611.         add     ebx,[code_start]
  3612.         add     ebx,34h
  3613.         mov     eax,edi
  3614.         sub     eax,[code_start]
  3615.         sub     eax,[ebx+4]
  3616.         mov     edx,edi
  3617.         cmp     edi,[undefined_data_end]
  3618.         jne     elf_exe_section_size_ok
  3619.         mov     edi,[undefined_data_start]
  3620.       elf_exe_section_size_ok:
  3621.         mov     [ebx+14h],eax
  3622.         add     eax,edi
  3623.         sub     eax,edx
  3624.         mov     [ebx+10h],eax
  3625.         mov     eax,[ebx+8]
  3626.         add     eax,[ebx+14h]
  3627.         add     eax,0FFFh
  3628.         and     eax,not 0FFFh
  3629.         ret
  3630.       elf64_exe_section:
  3631.         call    close_elf64_exe_section
  3632.         push    eax edx
  3633.         mov     ebx,[number_of_sections]
  3634.         imul    ebx,38h
  3635.         add     ebx,[code_start]
  3636.         add     ebx,40h
  3637.         cmp     ebx,[symbols_stream]
  3638.         jb      new_elf64_exe_section
  3639.         mov     ebx,[symbols_stream]
  3640.         sub     ebx,38h
  3641.         push    edi
  3642.         mov     edi,ebx
  3643.         mov     ecx,38h shr 2
  3644.         xor     eax,eax
  3645.         rep     stos dword [edi]
  3646.         pop     edi
  3647.         or      [next_pass_needed],-1
  3648.       new_elf64_exe_section:
  3649.         mov     byte [ebx],1
  3650.         mov     word [ebx+30h],1000h
  3651.       elf64_exe_section_flags:
  3652.         cmp     byte [esi],19h
  3653.         jne     elf64_exe_section_flags_ok
  3654.         lods    word [esi]
  3655.         sub     ah,28
  3656.         jbe     invalid_argument
  3657.         cmp     ah,1
  3658.         je      mark_elf64_exe_section_flag
  3659.         cmp     ah,3
  3660.         ja      invalid_argument
  3661.         xor     ah,1
  3662.         cmp     ah,2
  3663.         je      mark_elf64_exe_section_flag
  3664.         inc     ah
  3665.       mark_elf64_exe_section_flag:
  3666.         test    [ebx+4],ah
  3667.         jnz     setting_already_specified
  3668.         or      [ebx+4],ah
  3669.         jmp     elf64_exe_section_flags
  3670.       elf64_exe_section_flags_ok:
  3671.         mov     ecx,edi
  3672.         sub     ecx,[code_start]
  3673.         mov     [ebx+8],ecx
  3674.         pop     edx eax
  3675.         and     ecx,0FFFh
  3676.         add     eax,ecx
  3677.         adc     edx,0
  3678.         mov     [ebx+10h],eax
  3679.         mov     [ebx+10h+4],edx
  3680.         mov     [ebx+18h],eax
  3681.         mov     [ebx+18h+4],edx
  3682.         not     eax
  3683.         not     edx
  3684.         add     eax,1
  3685.         adc     edx,0
  3686.         add     eax,edi
  3687.         adc     edx,0
  3688.         mov     dword [org_origin],eax
  3689.         mov     dword [org_origin+4],edx
  3690.         mov     [org_registers],0
  3691.         mov     [org_start],edi
  3692.         inc     [number_of_sections]
  3693.         jmp     instruction_assembled
  3694.       close_elf64_exe_section:
  3695.         cmp     [number_of_sections],0
  3696.         jne     finish_elf64_exe_section
  3697.         cmp     edi,[symbols_stream]
  3698.         jne     first_elf64_exe_section_ok
  3699.         push    edi
  3700.         mov     edi,[code_start]
  3701.         add     edi,40h
  3702.         mov     ecx,38h shr 2
  3703.         xor     eax,eax
  3704.         rep     stos dword [edi]
  3705.         pop     edi
  3706.         mov     eax,[image_base]
  3707.         mov     edx,[image_base_high]
  3708.         ret
  3709.       first_elf64_exe_section_ok:
  3710.         inc     [number_of_sections]
  3711.       finish_elf64_exe_section:
  3712.         mov     ebx,[number_of_sections]
  3713.         dec     ebx
  3714.         imul    ebx,38h
  3715.         add     ebx,[code_start]
  3716.         add     ebx,40h
  3717.         mov     eax,edi
  3718.         sub     eax,[code_start]
  3719.         sub     eax,[ebx+8]
  3720.         mov     edx,edi
  3721.         cmp     edi,[undefined_data_end]
  3722.         jne     elf64_exe_section_size_ok
  3723.         mov     edi,[undefined_data_start]
  3724.       elf64_exe_section_size_ok:
  3725.         mov     [ebx+28h],eax
  3726.         add     eax,edi
  3727.         sub     eax,edx
  3728.         mov     [ebx+20h],eax
  3729.         mov     eax,[ebx+10h]
  3730.         mov     edx,[ebx+10h+4]
  3731.         add     eax,[ebx+28h]
  3732.         adc     edx,0
  3733.         sub     eax,1
  3734.         sbb     edx,0
  3735.         shrd    eax,edx,12
  3736.         shr     edx,12
  3737.         add     eax,1
  3738.         adc     edx,0
  3739.         shld    edx,eax,12
  3740.         shl     eax,12
  3741.         ret
  3742. close_elf_exe:
  3743.         test    [format_flags],8
  3744.         jnz     close_elf64_exe
  3745.         call    close_elf_exe_section
  3746.         mov     edx,[code_start]
  3747.         mov     eax,[number_of_sections]
  3748.         mov     byte [edx+1Ch],34h
  3749.         mov     [edx+2Ch],ax
  3750.         shl     eax,5
  3751.         add     eax,edx
  3752.         add     eax,34h
  3753.         cmp     eax,[symbols_stream]
  3754.         je      elf_exe_ok
  3755.         or      [next_pass_needed],-1
  3756.       elf_exe_ok:
  3757.         ret
  3758.       close_elf64_exe:
  3759.         call    close_elf64_exe_section
  3760.         mov     edx,[code_start]
  3761.         mov     eax,[number_of_sections]
  3762.         mov     byte [edx+20h],40h
  3763.         mov     [edx+38h],ax
  3764.         imul    eax,38h
  3765.         add     eax,edx
  3766.         add     eax,40h
  3767.         cmp     eax,[symbols_stream]
  3768.         je      elf64_exe_ok
  3769.         or      [next_pass_needed],-1
  3770.       elf64_exe_ok:
  3771.         ret
  3772.  
  3773. formatter_symbols:
  3774.  db 5,'align',1Ch,0
  3775.  db 6,'binary',18h,10h
  3776.  db 4,'code',19h,5
  3777.  db 4,'coff',18h,40h
  3778.  db 7,'console',1Bh,3
  3779.  db 4,'data',19h,6
  3780.  db 11,'discardable',19h,25
  3781.  db 3,'dll',1Bh,80h
  3782.  db 3,'elf',18h,50h
  3783.  db 5,'elf64',18h,58h
  3784.  db 10,'executable',19h,29
  3785.  db 6,'export',1Ah,0
  3786.  db 6,'fixups',1Ah,5
  3787.  db 3,'gui',1Bh,2
  3788.  db 6,'import',1Ah,1
  3789.  db 2,'ms',17h,41h
  3790.  db 4,'ms64',17h,49h
  3791.  db 2,'mz',18h,20h
  3792.  db 6,'native',1Bh,1
  3793.  db 11,'notpageable',19h,27
  3794.  db 2,'pe',18h,30h
  3795.  db 4,'pe64',18h,38h
  3796.  db 8,'readable',19h,30
  3797.  db 8,'resource',1Ah,2
  3798.  db 9,'shareable',19h,28
  3799.  db 3,'wdm',1Bh,81h
  3800.  db 8,'writable',19h,31
  3801.  db 9,'writeable',19h,31
  3802.  db 0
  3803.