Minimize the size of your program - assembly source

; based on tiny.asm, modified by xiangfan

;e_cblp 2b
;tbl 1b
;hexstr 1b
;LoaderFlags 4b

BITS 32

;
; MZ header
;
; The only two fields that matter are e_magic and e_lfanew

mzhdr:
    dw "MZ"       ; e_magic
    dw 0          ; e_cblp UNUSED

;
; PE signature
;

pesig:
    dd "PE"       ; e_cp UNUSED          ; PE signature
                  ; e_crlc UNUSED

;
; PE header
;

pehdr:
    dw 0x014C     ; e_cparhdr UNUSED     ; Machine (Intel 386)
    dw 1          ; e_minalloc UNUSED    ; NumberOfSections

    ;dd 0xC3582A6A ; e_maxalloc UNUSED    ; TimeDateStamp UNUSED <0xC>

start:
    jmp short main

tbl:
    db 1,1,2,3,7,5,6,4,8
    db 0 ;align 4

    ;dd 0          ; e_sp UNUSED          ; PointerToSymbolTable UNUSED
                  ; e_csum UNUSED

    ;dd 0          ; e_ip UNUSED          ; NumberOfSymbols UNUSED
                  ; e_cs UNUSED

    ;==4
    dw sections-opthdr ; e_lsarlc UNUSED ; SizeOfOptionalHeader
    dw 0x10F      ; e_ovno UNUSED        ; Characteristics

;
; PE optional header
;
; The debug directory size at offset 0x94 from here must be 0

filealign equ 4
sectalign equ 4   ; must be 4 because of e_lfanew

%define round(n, r) (((n+(r-1))/r)*r)

opthdr:
printf_:
    dw 0x10B      ; e_res UNUSED         ; Magic (PE32)
    ;db 8                                 ; MajorLinkerVersion UNUSED
    ;db 0                                 ; MinorLinkerVersion UNUSED

    ;dw 0x29E
    db "pr"

;
; PE code section
;

sections:
    ;dd 0                        ; SizeOfCode UNUSED                  ; Name UNUSED                
    ;dd 0          ; e_oemid UNUSED       ; SizeOfInitializedData UNUSED                                    
                  ; e_oeminfo UNUSED

    db "intf",0

    db 0,0,0 ;align

    dd codesize   ; e_res2 UNUSED        ; SizeOfUninitializedData UNUSED     ; VirtualSize
    ;==C
    dd start                             ; AddressOfEntryPoint                ; VirtualAddress
    dd codesize                          ; BaseOfCode UNUSED                  ; SizeOfRawData
    ;==C
    dd start                             ; BaseOfData UNUSED                  ; PointerToRawData

;
; Import table (array of IMAGE_IMPORT_DESCRIPTOR structures)
;

ImageBase equ 0x400000

idata:
    dd ImageBase                          ; ImageBase                          ; PointerToRelocations UNUSED ; OriginalFirstThunk UNUSED
    ;==4
    dd sectalign  ; e_lfanew             ; SectionAlignment                   ; PointerToLinenumbers UNUSED ; TimeDateStamp UNUSED
    ;==4
    dd filealign                         ; FileAlignment                      ; NumberOfRelocations UNUSED  ; ForwarderChain UNUSED
                                                                              ; NumberOfLinenumbers UNUSED
    dd msvcrt                            ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED      ; Name
                                         ; MinorOperatingSystemVersion UNUSED                               ; FirstThunk
    dd iat                               ; MajoirImageVersion UNUSED
                                         ; MinorImageVersion UNUSED
    dw 4                                 ; MajorSubsystemVersion                                            ; OriginalFirstThunk UNUSED
    ;dw 0                                 ; MinorSubsystemVersion UNUSED
    ;dd 0                                 ; Win32VersionValue UNUSED                                         ; TimeDateStamp UNUSED
hexstr:
    db "%08X",0
    db 0 ;align

    dd round(hdrsize, sectalign)+round(codesize,sectalign) ; SizeOfImage                                    ; ForwarderChain UNUSED
    ;==8C
    dd round(hdrsize, filealign)         ; SizeOfHeaders                                                    ; Name UNUSED
    dd 0                                 ; CheckSum UNUSED                                                  ; FirstThunk

idatasize equ $ - idata

    dw 3                                 ; Subsystem (Win32 Console)
    ;dw 0                                 ; DllCharacteristics UNUSED
sstr:
    db "%s"
    dd 0                                 ; SizeOfStackReserve
    dd 0                                 ; SizeOfStackCommit
    dd 0                                 ; SizeOfHeapReserve
    dd 0                                 ; SizeOfHeapCommit
    ;dd 0                                 ; LoaderFlags UNUSED
dstr:
    db "%d",0
    db 0
    dd 2                                 ; NumberOfRvaAndSizes

;
; The DLL name should be at most 16 bytes, including the null terminator
;

;
; Data directories
;
; The debug directory size at offset 0x34 from here must be 0

scanf_:
newline:
    db 10,0
;dw 0x2AB
db "scanf",0

    ;dd 0                                 ; Export Table UNUSED
    ;dd 0

    ;==38
    dd idata - $$                        ; Import Table

hdrsize equ $ - $$

main:
var_42C    equ -42Ch
var_28        equ -28h
var_18        equ -18h
;var_14        equ -14h
;var_10        equ -10h
;var_C        equ -0Ch
;var_8        equ -8
;var_4        equ -4
        enter    42Ch, 0
        push    esp    ;[ebp+42C]
        ;push    dstr+ImageBase    ; "%d"
        ;call    [scanf+ImageBase]
        mov    eax, dstr+ImageBase
        push    eax
        add    al, scanf-dstr
        call    [eax]
        pop    eax    ;dstr
        pop    ecx
        ;pushad    ;ebx,esi,edi
        mov    edi, [ecx]
        test    edi, edi
        jle    short loc_4002D0
        ;times 4 db 0
        add    al, newline-dstr
loc_400235:                ; CODE XREF: start+100j
        ;lea    esi, [esp]    ;pushad==20h
        push    esp
        add    al, sstr-newline
        push    eax
        nop
        jmp    short skip_debug
iat:
printf:
        dd printf_
scanf:
        dd scanf_
        ;dd 0
        times 4 db 0 ;ensure debug directory size is 0
skip_debug:
        add    al, scanf-sstr
        call    [eax]
        pop    esi    ; "%s"
        pop    esi

        ;push    sstr+ImageBase    ; "%s"
        ;call    [scanf+ImageBase]
        ;pop    ecx
        ;pop    ecx
        ;mov    dword [ebp+var_18], 0CBDCEDFEh
        ;mov    dword [ebp+var_14], 8798A9BAh
        ;mov    dword [ebp+var_10], 43546576h
        ;mov    dword [ebp+var_C], 102132h

        lea    edx, [ebp+var_18-1]
        ;xor    ecx, ecx
        xchg    eax, ecx
        mov    cl, 16
        mov    al, 0FEh
loc_4:
        inc    edx
        mov    [edx], al
        sub    al, 11h
        loop    loc_4
        ;mov    byte [edx], 0
        inc    byte [edx]

loc_400272:                ; CODE XREF: start+D0j
        ;movsx    ebx, byte [esi]
        ;inc    esi
        lodsb
        movsx    ebx, al
        test    ebx, ebx
        jz    short loc_4002DA
        pusha    ;edi,esi
        and    al, 0Fh
        xchg    eax, ebx
        ;mov    eax, ebx
        cdq
        ;xor    ecx, ecx    ;ecx is alway =0 here
        mov    cl, 9
        idiv    ecx
        mov    cl, 4
        test    edx, edx
        lea    edi, [ebp+var_18]
        jl    short loc_40028F
        mov    dl, byte [edx+tbl+ImageBase]
loc_40028F:                ; CODE XREF: start+9Aj
        mov    eax, edx
        imul    eax, dword [edi]
        add    eax, 0FBFCh
        stosd
        loop    loc_40028F

        ;xor    ecx, ecx
        ;and    bl, 0Fh
        mov    cl, 10h
        sub    cl, bl
        mov    esi, edi
        sub    esi, ecx
        lea    edi, [ebp+var_28]
        push    edi
        rep    movsb
        mov    cl, bl
        lea    esi, [ebp+var_18]
        rep    movsb
        ;lea    esi, [ebp+var_28]
        pop    esi
        mov    cl, 10h
        rep    movsb
        popa
        jmp    short loc_400272
loc_4002D0:
        jmp    short loc_400311
loc_4002D2:
        jmp    short loc_400235
; ---------------------------------------------------------------------------

loc_4002DA:                ; CODE XREF: start+6Cj
        lea    esi, [ebp+var_18]
        mov    bl, 4
loc_4002E0:                ; CODE XREF: start+EBj
        lodsd
        push    eax
        ;push    hexstr+ImageBase    ; "%08X"
        ;call    [printf+ImageBase]
        mov    eax, hexstr+ImageBase
        push    eax
        add    al, printf-hexstr
        call    [eax]
        pop    eax
        dec    ebx    ;ebx==0 after 2DA
        pop    ecx
        jnz    short loc_4002E0

        ;push    newline+ImageBase ; "\n"
        ;call    [printf+ImageBase]
        add    al, newline-hexstr
        push    eax
        add    al, printf-newline
        call    [eax]
        dec    edi
        pop    eax
        jnz    loc_4002D2

loc_400311:                ; CODE XREF: start+1Ej
        ;popad
        ;xor    eax, eax
        leave
        retn

msvcrt:
    db "msvcrt", 0

codesize equ $ - start

filesize equ $ - $$