tôi có chương trình C sau:Làm thế nào để tạo PE nhỏ (Win32) thực thi sử dụng MinGW
#include <windows.h>
void __cdecl mainCRTStartup() {
DWORD bw;
HANDLE hfile = GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(hfile, "Hello, World!\r\n", 15, &bw, 0);
ExitProcess(0); /* Needed for successful (0) exit. */
}
tôi biên dịch nó với GCC 4.8.2, sử dụng dòng lệnh sau:
i686-w64-mingw32-gcc -s -Os -fno-ident -fno-stack-protector -fomit-frame-pointer \
-fno-unwind-tables -fno-asynchronous-unwind-tables -falign-functions=1 \
-mpreferred-stack-boundary=2 -falign-jumps=1 -falign-loops=1 -mconsole \
-nostdlib -nodefaultlibs -nostartfiles -o h.exe h.c -lkernel32
Tệp .exe được tạo dài 2048 byte. Làm thế nào tôi có thể làm cho nó nhỏ hơn bằng cách sử dụng MinGW, tốt nhất là tối đa 1024 byte, hoặc (thậm chí tốt hơn) tại nhiều nhất 512 byte?
Tôi muốn có giải pháp mà không cần viết mã lắp ráp, nhưng tôi cũng quan tâm đến các giải pháp lắp ráp.
Tôi đã thử -Wl,-N
để giảm số lượng phần (phân đoạn), nhưng điều đó gây ra sự phân đoạn khi chạy .exe trong Wine.
Điều này article cho thấy rằng 480 byte là có thể. Cài đặt này sử dụng các cài đặt sau:
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")// Merge sections
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma comment(linker, "/MERGE:.reloc=.data")
#pragma optimize("gsy", on)
Thật không may là #pragma
không hoạt động với MinGW GCC. Có tương đương không?
Trong here Tôi có thể tìm thấy cờ GCC -Wl,--section-alignment,16,--file-alignment,16
làm giảm kích thước .exe xuống 752 byte. The .exe dường như làm việc trong Wine.
Bằng modifying the linker script Tôi có thể hợp nhất .data
và .rdata
và giảm xuống 736 byte. Tôi đang sử dụng các cờ GCC này ngoài các cờ trên: -Wl,--section-alignment,16,--file-alignment,16,-T,tinygccpe.scr
.
Tôi vẫn đang tìm kiếm số tiền tương đương MinGW là /MERGE
.
This question tương tự, nhưng không cố gắng đi dưới 9000 byte.
Tôi cũng đang tìm kiếm một công cụ strip
(lệnh strip
trong MinGW không làm giảm kích thước .exe thêm nữa) mà có thể loại bỏ các cuống DOS (đó là giữa offsets 0x40 và 0x80, nó chứa This program cannot be run in DOS mode.
, chúng tôi có thể tiết kiệm 64 byte). This code có thể xóa nó, nhưng nó cũng phá vỡ tất cả các offsets tuyệt đối trong .exe. Thật không may, mối liên kết ld
trong MinGW không thể xóa phần gốc DOS, nó được mã hóa cứng trong tệp bfd/peXXigen.c
, ngay phía trên NT_SIGNATURE
.
Có thể tách nhiều tiêu đề hơn khỏi tiêu đề .exe, tức là trình tải không sử dụng không?
Bài viết được liên kết rất cũ. Đó là về VC++ 6, được phát hành vào năm 1998. Động lực để cố gắng tạo ra một nhị phân không có gì là cực nhỏ? Để làm bất cứ điều gì hiệu quả, bạn sẽ muốn liên kết trong một thư viện thời gian chạy, mà sẽ làm cho nhị phân của bạn lớn một lần nữa. Tôi chắc chắn không ủng hộ viết * bloated * code (rất chống lại điều đó, quá), nhưng bạn đang nghiêng tại cối xay gió ở đây, theo ý kiến của tôi. Có nhiều lý do tại sao các trình liên kết chèn đệm vào và nó không quan trọng một khi bạn có số lượng mã không nhỏ. (Tuy nhiên, hãy bình chọn lên — đó là một câu hỏi khá hay.) –
@Cody Grey: Động lực của tôi về tiết kiệm 1536 tiêu đề PE và byte soạn sẵn chủ yếu là học thuật. Những byte này có lẽ sẽ không mang lại lợi ích đáng kể cho người dùng với một hệ thống multi-gigabyte-RAM hiện đại. Tôi cũng đang phát triển một số chương trình với tổng số lượng mã nhỏ (nhỏ hơn 50 000 byte khi được biên dịch với các cài đặt ở trên). – pts
Hãy nhớ rằng có kích thước cụm tối thiểu trên phương tiện lưu trữ. ví dụ. trên Windows, điều này thường là 4k. Ngay cả khi bạn quản lý để có được các mối liên kết để tạo ra một thực thi nhỏ hơn nó vẫn sẽ mất nhiều không gian trên đĩa. – greatwolf