FASM ile derlenmiş x86 ASM EXE boyutunu azaltmak için nasıl?


14

Bir alıştırma olarak, bu meydan okuma için x86 Montaj Dili'nde basit bir çözüm oluşturdum . Bunu Windows'ta FASM ile çalıştırıyorum. İşte kaynak kodum:

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'

Bunu derlediğimde, beklediğimden daha büyük bir yürütülebilir dosya alıyorum. İşte bir hexdump:

https://pastebin.com/W5sUTvTe

Kod bölümü ile veri ve kütüphane içe aktarma bölümleri arasında çok fazla boş alanın yanı sıra, kodda gömülü "Bu program DOS modunda çalıştırılamaz" diyen bir ileti olduğunu fark ettim. Kaynak kodumu Code Golf için uygun olan küçük bir dosyaya nasıl monte edebilirim?

Bir yan not olarak, stdoutiçe aktarmadan msvcrtve çağırmadan yazdırmanın daha iyi yolları için öneriler printfbekliyoruz.


@iBug Bunu duyduğuma üzüldüm. Bana sormam için daha uygun bir yer önerebilir misiniz?
vasilescur

12
@iBug Belirli durumlarda golf yardımı isteyen sorular burada kesinlikle konu dışı değildir .
AdmBorkBork


1
Bu olmalıdır: start: push char Lb: call [printf] call [printf] call [printf] call [printf] inc [char] cmp [char], 'Z' jle Lb çünkü değilse yığını yığabilir ; biri printf her çağrı esp ayarlamak talimat eklemek
gerekip gerekmediğini görmek gerekir

1
printf yerine, kernel32 dışında bir ithalata ihtiyaç duymadan WriteFile (stdout) yapabilirsiniz (varsayılan olarak bulunur, sadece adresi belirlemeniz gerekir)
peter ferrie

Yanıtlar:


2

Biraz genel ipucu, ama

PE EXE yerine COM dosya biçimini kullanın.

PE EXE kod-golf biçimini hemen hemen işe yaramaz hale birkaç kusurları vardır. Birincisi, görüntü hizalama (Windows düzgün bir şekilde hizalanmamışsa EXE dosyasını çalıştırmaz) ve ikincisi başlık boyutudur. Bu kadar önemli olmayan birkaç faktör vardır (yürütülebilir dosyayı bölümlere ayırmak).

COM dosya biçimini kullanmanın avantajları (düz ikilikle neredeyse eşdeğerdir)

  • Sıfır başlık kodu, dosya bölümlere ayrılmamış
  • Görüntü hizalama yok (bu nedenle görüntü boyutu, kesin olarak tanımlanmış iki güçle bölünemeyebilir, ancak 65K'dan küçük olması gerekir. Ters giden birşey mi var).
  • Harici kütüphaneleri kullanamazsınız - bu aslında bir artıdır, çünkü şüphesiz I / O gerçekleştirmek için başka bir yolunuz vardır. BIOS kesintileri işte burada devreye girer.
  • Bellek ve sisteme bağlı cihazlar üzerinde doğrudan kontrolünüz vardır, bu nedenle disk belleği, erişim ihlali, bellek koruması, eşzamanlılık vb. Yoktur. Bu özellikler gerçekten yaratıcı programların golf oynamasını kolaylaştırır.

Kodunuzu düz ikili olarak çalışacak şekilde revize ettim. Çok basit:

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

Çıkış ikili dosyası sadece 32 bayt büyüklüğündedir. Boyutu daha da azaltmak mümkün olduğuna inanıyorum, ama bu sadece bir başlangıç ​​noktası.

İle birleştirin nasm -fbin file.asm -o file.com. Bu örnek NASM için yapılmıştır, ancak FASM'ye serbestçe çevirebilirsiniz ve kusursuz bir şekilde çalışacaktır.


Bu soruya cevap verdiğim ve Google'dan geri döndüğüme inanamıyorum
Krzysztof Szewczyk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.