少年,你的一個Hello World 有多小?

起因如上……


額,先把平臺放一下,因爲有些代碼設計系統架構,如果你是x86 的架構需要自己修改代碼:



首先是平時調用glibc 的C 程序:

#include <stdio.h>

int
main (void) {
        printf ("Hello World!\n");
        return 0;
}
看一下大小,哇,足足有將近7KB:


階段1:在平時的基礎上使用strip

恩不錯,還剩4K 多一點:


階段2:不使用glibc 並且strip

哇!只剩下520B 了有木有!直接調用系統調用竟然把可執行文件的體積縮小了這麼多!

.section        .data
aStr: .ascii "Hello World!\n"
aStrEnd:

.section        .text
.global _start
_start:
        movq    $1, %rdi
        movq    $aStr, %rsi
        movq    $(aStrEnd-aStr), %rdx
        movq    $1, %rax
        syscall

        movq    $0, %rdi
        movq    $60, %rax
        syscall


階段3:克勤克儉用指令體積

我們應該儘量減少指令編譯後形成機器碼的體積,儘量使之最小!

哇!通過精心的挑選指令,ELF 文件體積減小到了496 B:

.section        .data
aStr: .ascii "Hello World!\n"
aStrEnd:

.section        .text
.global _start
_start:
        movw    $1, %di
        movl    $aStr, %esi
        movb    $(aStrEnd-aStr), %dl
        movb    $1, %al
        syscall

        xor     %di, %di
        movb    $60, %al
        syscall


階段4:不再使用段

就是這樣,喵,當然strip 還是要的,看看怎麼樣,哇,新的記錄368 字節:

aStr: .ascii "Hello World!\n"
aStrEnd:

.global _start
_start:
        movw    $1, %di
        movl    $aStr, %esi
        movb    $(aStrEnd-aStr), %dl
        movb    $1, %al
        syscall

        xor     %di, %di
        movb    $60, %al
        syscall


階段5:目標文件中“沒用”的東西統統扔掉!

上面分別使用syscall 代替了glibc,調整了指令的大小,並且去掉了分段,接下來在這個基礎上對ELF 下手吧!

先看看有用的東西(ELF 頭、程序頭和節頭)有多少,64+56+64 = 184B:

只留下這184B,剩下的統統不要了!


最後的到了什麼?瞧!一個不到200 字節的Hello World!讓我們掐去腦袋,它可以給你提供……

發佈了41 篇原創文章 · 獲贊 13 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章