¿Cómo reducir el tamaño EXE de ASM x86 compilado con FASM?

14

Como ejercicio, he creado una solución simple para este desafío, en x86 Assembly Language. Estoy ejecutando esto con FASM en Windows. Aquí está mi código fuente:

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'

Cuando compilo esto, obtengo un ejecutable más grande de lo que esperaba. Aquí hay un hexdump:

https://pastebin.com/W5sUTvTe

Noté que hay mucho espacio vacío entre la sección de código y las secciones de importación de datos y biblioteca, así como un mensaje que dice "Este programa no se puede ejecutar en modo DOS" incrustado en el código. ¿Cómo puedo ensamblar mi código fuente en un archivo pequeño, adecuado para Code Golf?

Como nota al margen, las sugerencias sobre mejores formas de imprimir stdoutsin importar msvcrty llamar printfson bienvenidas

vasilescur
fuente
@iBug Lamento escuchar eso. ¿Podría sugerirme un lugar más adecuado para que pregunte?
vasilescur
12
Las preguntas de @iBug Tips que piden ayuda para jugar golf en casos específicos definitivamente no están fuera de tema aquí.
AdmBorkBork
12
Meta relevante
AdmBorkBork
1
Tiene que ser: start: push char Lb: call [printf] call [printf] call [printf] call [printf] inc [char] cmp [char], 'Z' jle Lb porque si no, podría consumir la pila ; uno tiene que ver si cada llamada a printf tiene que agregar la instrucción que ajusta esp
RosLuP
1
en lugar de printf, puede WriteFile (stdout), que no necesita de las importaciones que no sean kernel32 (que está presente de forma predeterminada, sólo tiene que determinar la dirección)
Peter Ferrie

Respuestas:

2

Un consejo bastante general, pero

Utilice el formato de archivo COM en lugar de PE EXE.

PE EXE tiene algunos defectos que hacen que el formato sea bastante inútil en code-golf. El primero es la alineación de la imagen (Windows no ejecutará el archivo EXE si no está alineado correctamente), y el segundo es el tamaño del encabezado. Hay algunos factores que no son tan importantes (dividir el ejecutable en secciones).

Las ventajas de usar el formato de archivo COM (que es más o menos equivalente al binario plano) son:

  • Código de encabezado cero, el archivo no está dividido en secciones
  • No se alinea la imagen (por lo que el tamaño de la imagen puede no ser divisible por una potencia estrictamente definida de dos, pero tiene que ser menor que 65 K. Sin embargo, no cambia mucho, porque si su envío es mayor que 65 K, está haciendo algo mal).
  • No puede usar bibliotecas externas, esto es realmente una ventaja, porque sin duda tiene otra forma de realizar E / S. Ahí es donde las interrupciones del BIOS son útiles.
  • Usted tiene control directo sobre la memoria y los dispositivos vinculados al sistema, por lo tanto, no hay paginación, no hay violaciones de acceso, no hay protección de memoria, no hay concurrencia, etc. Estas características facilitan el golf en programas realmente creativos.

Revisé su código para que funcione como binario plano. Es muy simple:

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, "$"

El binario de salida tiene solo 32 bytes. Creo que es posible reducir aún más el tamaño, pero este es solo un punto de partida.

Montar con nasm -fbin file.asm -o file.com. Tenga en cuenta que este ejemplo se ha creado para NASM, pero puede traducirlo libremente a FASM y funcionará perfectamente.

Krzysztof Szewczyk
fuente
No puedo creer que haya respondido a esta pregunta y haya regresado a ella desde google
Krzysztof Szewczyk