News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Make output .exe smaller?

Started by Astro, July 07, 2009, 12:50:43 PM

Previous topic - Next topic

Astro

Hi,

.386
.model flat,stdcall

include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

.data
s db "Test",0

.code
start:
lea eax,s
push eax
call StdOut
ret
end start


Results in a binary 2,560 bytes long. Can this be reduced at all?

mitchi

You could save an easy 512 k by merging the data section with the code section.

jj2007

1024 bytes with polink, /MERGE:.data=.rdata /MERGE:.rdata=.text

hutch--

This will give you 1.5k with normal assemble and link.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

    txt db "Howdy",0    ; in CODE section but before "start" label.

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    invoke StdOut,OFFSET txt
    invoke ExitProcess,0

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Astro

Is there any reason not to merge .data with .code sections?

When I looked in the original EXE with a hex editor I noticed the data (region?) started at offset 0x800 and ended at 0x9ff (EOF), whilst the code (region?) started at offset 0x400, and ended at 0x7ff.

Now the code (region?) starts at 0x200 and ends at 0x5ff (EOF).

That single change knocked 1024 bytes out of it.

I'm just trying to figure out what it is doing/how it is laid out. :)

jj2007

Quote from: Astro on July 07, 2009, 03:31:19 PM
Is there any reason not to merge .data with .code sections?

Data will be read only...

Vortex

Hi Jochen,

You can change the attributes of sections with the linker switch /SECTION

Hi Astro,

Here is an example without combining the sections. The final EXE size is 1024 bytes and the it does not import any function but no guarantee that the EXE will work on every version of Windows. You can find other routines to get the base of kernel32.dll

.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc

szCmp       PROTO :DWORD,:DWORD
GetProcAddr PROTO :DWORD,:DWORD

.code

s               db "Test",0
LoadLibrary     db "LoadLibraryA",0
FreeLibrary     db "FreeLibrary",0
ExitProcess     db "ExitProcess",0
printf          db "printf",0
dll             db "msvcrt.dll",0


start:

    mov     ecx,[esp]

GetKrnlBaseLoop:

    xor     edx,edx
    dec     ecx
    mov     dx,[ecx+03ch]
    test    dx,0f800h
    jnz     GetKrnlBaseLoop
    cmp     ecx,[ecx+edx+34h]
    jnz     GetKrnlBaseLoop

    push    esi
    push    edi

    mov     esi,ecx         ; esi -> handle to kernel32.dll

    invoke  GetProcAddr,esi,ADDR LoadLibrary

    push    OFFSET dll
    call    eax
    mov     edi,eax

    invoke  GetProcAddr,eax,ADDR printf

    push    OFFSET s
    call    eax
    add     esp,4

    invoke  GetProcAddr,esi,ADDR FreeLibrary
    push    edi
    call    eax
   
    invoke  GetProcAddr,esi,ADDR ExitProcess

    pop     edi
    pop     esi

    push    0
    call    eax

include     GetProcAddr.inc
include     szCmp.inc

END start

[attachment deleted by admin]

dedndave

Erol (Vortex) suggested to me that using PoLink instead of Link can result in smaller exe's

Astro

@Vortex: Thanks for the example! :U I think I'm keeping up so far!  :dazzled:

@dedndave: I think this is mentioned in the examples shipped with the MASM package. I'll have a look.

BlackVortex

Quote from: jj2007 on July 07, 2009, 01:31:58 PM
1024 bytes with polink, /MERGE:.data=.rdata /MERGE:.rdata=.text
Yep   :U

Astro

Quote from: jj2007 on July 07, 2009, 05:09:21 PM
Quote from: Astro on July 07, 2009, 03:31:19 PM
Is there any reason not to merge .data with .code sections?

Data will be read only...
So if the data is in the .code section, I can't modify it progmatically, but could if it appeared in the .data section?

hutch--

Astro,

If you have some reason to modify your own code at runtime, learn both the linker attributes for setting an app to READ/WRITE/EXECUTE and then test it under DEP to ensure it works correctly. You may have to use VirtualProtect() on at least some memory range if you have some need to write to the code section.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

eliminating the data segment shouldn't reduce the exe size by much
i am guessing the align type for the segments is 16 ?
that means it may save you 15 bytes, plus an entry in the PE header
by the time you add the VirtualProtect code, it's a wash

Astro

Hi,

@hutch--: Thanks. I don't have a need to at the moment, but was something I just wanted clarifying for the future. :)

@dedndave: I think it knocked 512 bytes off the exe size, but how much space is actually left over before it increases the file size again due to other factors is an interesting point. Could be self-defeating when the file size is really small.

dedndave

yah - 32-bit doesn't have ".COM" programs like DOS - i miss those - lol
at least half the apps i wrote were .COM programs