Come ridurre la dimensione EXE di x86 ASM compilata con FASM?


14

Come esercizio, ho creato una soluzione semplice per questa sfida, in x86 Assembly Language. Sto eseguendo questo con FASM su Windows. Ecco il mio codice sorgente:

format PE console
entry start

include 'WIN32A.inc'

section '.text' code executable
start:
    push    char            ; Start at 'A'
    call    [printf]        ; Print the current letter 4 times
    call    [printf]
    call    [printf]
    call    [printf]
    inc     [char]          ; Increment the letter
    cmp     [char], 'Z'     ; Compare to 'Z'
    jle     start           ; char <= 'Z' --> goto start

section 'r.data' data readable writeable
    char    db  'A', 10, 0  ; Stores the current letter

section '.idata' data readable import
    library  msvcrt,   'msvcrt.dll'
    import   msvcrt, printf, 'printf'

Quando compilo questo, ottengo un eseguibile più grande di quanto mi aspettassi. Ecco un hexdump:

https://pastebin.com/W5sUTvTe

Ho notato che c'è molto spazio vuoto tra la sezione del codice e le sezioni di importazione dei dati e della libreria, nonché un messaggio che dice "Impossibile eseguire questo programma in modalità DOS" incorporato nel codice. Come posso assemblare il mio codice sorgente in un piccolo file, adatto per Code Golf?

Come nota a stdoutmargine, sono ben accetti suggerimenti su modi migliori per stampare senza importare msvcrte chiamare printf.


@iBug Mi dispiace sentirlo. Potresti suggerire un posto più adatto per me?
vasilescur,

12
domande @iBug Consigli chiedono golf aiuto in casi specifici sono la maggior parte sicuramente non fuori tema qui.
AdmBorkBork,


1
Deve essere: start: push char Lb: call [printf] call [printf] call [printf] call [printf] inc [char] cmp [char], 'Z' jle Lb perché, in caso contrario, si potrebbe consumare lo stack ; bisogna vedere se ogni chiamata a printf deve aggiungere le istruzioni che regolano esp
RosLuP

1
invece di printf, puoi scrivere WriteFile (stdout), senza bisogno di importare altro che kernel32 (che è presente di default, devi solo determinare l'indirizzo)
peter ferrie

Risposte:


2

Abbastanza un suggerimento generale, ma

Utilizzare il formato di file COM anziché PE EXE.

PE EXE ha alcuni difetti che rendono il formato praticamente inutile nel code-golf. Il primo è l'allineamento dell'immagine (Windows non eseguirà il file EXE se non è allineato correttamente) e il secondo è la dimensione dell'intestazione. Ci sono alcuni fattori che non sono così importanti (dividendo l'eseguibile in sezioni).

I vantaggi dell'utilizzo del formato di file COM (che è praticamente equivalente al binario flat) sono:

  • Zero header code, il file non è diviso in sezioni
  • Nessun allineamento delle immagini (quindi la dimensione dell'immagine potrebbe non essere divisibile per una potenza strettamente definita di due, ma deve essere inferiore a 65 K. Tuttavia non cambia molto, perché se l'invio è maggiore di 65 KB, lo stai facendo Qualcosa non va).
  • Non puoi usare librerie esterne - questo è in realtà un vantaggio, perché senza dubbio hai un altro modo per eseguire l'I / O. Ecco dove gli interrupt del BIOS sono utili.
  • Hai il controllo diretto sulla memoria e sui dispositivi collegati al sistema, quindi non ci sono paging, nessuna violazione di accesso, nessuna protezione della memoria, nessuna concorrenza, e così via. Queste funzionalità semplificano il golf di programmi davvero creativi.

Ho modificato il tuo codice in modo che funzioni come binario piatto. È morto semplice:

ORG 100H

MOV DX, P
MOV AH, 9

L:
    INT 21H
    INT 21H
    INT 21H
    INT 21H

    INC BYTE [P]
    CMP BYTE [P], 'Z'
    JLE L

MOV AX, 4C00h
INT 21h

P DB "A", 10, "$"

Il file binario di output ha una dimensione di soli 32 byte. Credo che sia possibile ridurre ulteriormente le dimensioni, ma questo è solo un punto di partenza.

Assemblare con nasm -fbin file.asm -o file.com. Nota, questo esempio è stato creato per NASM, ma puoi tradurlo liberamente in FASM e funzionerà perfettamente.


Non riesco a credere di aver risposto a questa domanda e di esserci tornato da Google
Krzysztof Szewczyk
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.