Comment réduire la taille EXE de x86 ASM compilé avec FASM?

14

Comme exercice, j'ai créé une solution simple pour ce défi, en langage d'assemblage x86. J'exécute cela avec FASM sur Windows. Voici mon code source:

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'

Lorsque je compile ceci, j'obtiens un exécutable plus grand que prévu. Voici un hexdump:

https://pastebin.com/W5sUTvTe

Je remarque qu'il y a beaucoup d'espace vide entre la section de code et les sections d'importation de données et de bibliothèque, ainsi qu'un message disant "Ce programme ne peut pas être exécuté en mode DOS" incorporé dans le code. Comment assembler mon code source dans un petit fichier adapté à Code Golf?

En guise de remarque, les suggestions de meilleures façons d'imprimer stdoutsans importer msvcrtni appeler printfsont les bienvenues.

vasilescur
la source
@iBug Je suis désolé d'entendre ça. Pourriez-vous s'il vous plaît suggérer un endroit plus approprié pour moi de demander?
vasilescur
12
@iBug Tips, les questions demandant de l'aide au golf dans des cas spécifiques ne sont certainement pas hors sujet ici.
AdmBorkBork
12
Méta pertinente
AdmBorkBork
1
Il doit être: start: push char Lb: call [printf] call [printf] call [printf] call [printf] inc [char] cmp [char], 'Z' jle Lb car sinon, pourrait être consommer la pile ; il faut voir si à chaque appel à printf il faut ajouter l'instruction qui ajuste esp
RosLuP
1
au lieu de printf, vous pouvez WriteFile (stdout), ne nécessitant aucune importation autre que kernel32 (qui est présent par défaut, il vous suffit de déterminer l'adresse)
peter ferrie

Réponses:

2

Astuce assez générale, mais

Utilisez le format de fichier COM au lieu de PE EXE.

PE EXE a quelques défauts rendant le format pratiquement inutile dans le code-golf. Le premier est l'alignement de l'image (Windows n'exécutera pas le fichier EXE s'il n'est pas correctement aligné), et le second est la taille de l'en-tête. Il y a quelques facteurs qui ne sont pas si importants (diviser l'exécutable en sections).

Les avantages de l'utilisation du format de fichier COM (qui est à peu près équivalent au binaire plat) sont les suivants:

  • Code d'en-tête zéro, le fichier n'est pas divisé en sections
  • Pas d'alignement de l'image (donc la taille de l'image peut ne pas être divisible par une puissance strictement définie de deux, mais elle doit être inférieure à 65 Ko. Cela ne change cependant pas grand-chose, car si votre soumission est supérieure à 65 Ko, vous faites Quelque chose ne va pas).
  • Vous ne pouvez pas utiliser de bibliothèques externes - c'est en fait un avantage, car vous avez sans aucun doute une autre façon d'effectuer des E / S. C'est là que les interruptions du BIOS sont utiles.
  • Vous avez un contrôle direct sur la mémoire et les périphériques connectés au système, il n'y a donc pas de pagination, pas de violation d'accès, pas de protection de la mémoire, pas de simultanéité, etc. Ces fonctionnalités facilitent le golf de programmes vraiment créatifs.

J'ai révisé votre code pour qu'il fonctionne en binaire plat. C'est très 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, "$"

Le binaire de sortie ne fait que 32 octets. Je pense qu'il est possible de réduire encore la taille, mais ce n'est qu'un point de départ.

Assemblez avec nasm -fbin file.asm -o file.com. Remarque, cet exemple a été fait pour NASM, mais vous pouvez le traduire librement en FASM, et cela fonctionnera parfaitement.

Krzysztof Szewczyk
la source
Je ne peux pas croire que j'ai répondu à cette question et que j'y suis retourné depuis Google
Krzysztof Szewczyk