FASMでコンパイルされたx86 ASMのEXEサイズを減らす方法は?


14

演習として、x86アセンブリ言語でこの課題に対する簡単なソリューションを作成しました。これをWindowsのFASMで実行しています。これが私のソースコードです。

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'

これをコンパイルすると、予想よりも大きな実行可能ファイルが得られます。hexdumpは次のとおりです。

https://pastebin.com/W5sUTvTe

コードセクションとデータおよびライブラリインポートセクションの間に多くの空きスペースがあり、コードに「このプログラムはDOSモードで実行できない」というメッセージが埋め込まれていることに気付きました。コードゴルフに適した小さなファイルにソースコードをアセンブルするにはどうすればよいですか?

補足として、stdoutインポートmsvcrtや呼び出しを行わずに印刷するためのより良い方法の提案をprintf歓迎します。


@iBugそれを聞いてすみません。私が尋ねるのにより適した場所を提案してもらえますか?
vasilescur

12
特定のケースでゴルフの助けを求める@iBug Tipsの質問は、ここではほとんど間違いありません
AdmBorkBork


1
start:push char Lb:call [printf] call [printf] call [printf] call [printf] inc [char] cmp [char]、 'Z' jleLb。そうでない場合、スタックを消費する可能性があるため; printfを呼び出すたびに、espを調整する命令を追加する必要があるかどうかを確認する必要があります
RosLuP

1
printfの代わりに、WriteFile(stdout)を使用できます。kernel32以外のインポートは不要です(デフォルトで存在するため、アドレスを決定する必要があります)
peter ferrie

回答:


2

かなり一般的なヒントですが、

PE EXEの代わりにCOMファイル形式を使用します。

PE EXEには、code-golfでフォーマットをほとんど役に立たなくするいくつかの欠陥があります。1つ目は画像の位置合わせです(適切に位置合わせされていないと、WindowsはEXEファイルを実行しません)、2つ目はヘッダーサイズです。重要ではない要素がいくつかあります(実行可能ファイルをセクションに分割する)。

COMフ​​ァイル形式(フラットバイナリとほぼ同等)を使用する利点は次のとおりです。

  • ヘッダーコードはゼロ、ファイルはセクションに分割されていません
  • 画像の調整なし(したがって、画像サイズは厳密に定義された2の累乗で割り切れない場合がありますが、65Kより小さくする必要があります。ただし、送信が65Kよりも大きい場合は、何か問題でも)。
  • 外部ライブラリを使用することはできません-これは実際にはプラスです。なぜなら、間違いなくI / Oを実行する他の方法があるからです。ところですBIOSの割り込みが便利来ます。
  • システムにリンクされているメモリとデバイスを直接制御できるため、ページング、アクセス違反、メモリ保護、同時実行などはありません。これらの機能により、本当に創造的なプログラムを簡単にゴルフできます。

フラットバイナリとして機能するようにコードを修正しました。それは非常に簡単です:

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

出力バイナリのサイズはわずか32バイトです。サイズをさらに小さくすることは可能だと思いますが、これは出発点にすぎません。

で組み立てnasm -fbin file.asm -o file.comます。この例はNASM向けに作成されていますが、FASMに自由に変換でき、問題なく動作します。


私はこの質問に答えてGoogleからのそれに戻って行きました信じることができない
クシシュトフSzewczyk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.