2012年2月14日 星期二

有趣的ELF觀察

如果要寫個印出"Hello World!"字串的程式,大概很多人都會,簡單的用printf就可以達成,不消幾行codes,那麼大小呢?

  • a.out是使用一般編譯(gcc test.c這樣),因為library放在外面,所以大小大約7kB
  • b.out跟著使用-static引入所有lib,可怕的大啊,變成了570kB左右的大小,請比較一下busybox,就可以感受到busybox的威力,小小印個"Hello World!"就要這樣的size,busybox可是支援數十道指令阿!!
  • 最後是tinytest.c所編譯出來的,他刪除了呼叫glibc.lib的必要性,並且使用了組合語言,整體大小就小了很多


tinytest.c內容如下
編譯指令如下
gcc -c -fno-builtin tinytest.c
ld -static -e mymain -o tinytest tinytest.o
可以注意到整個程式沒有main(),我們使用ld指令來指定entry function,exit()這個function其實可以從include/unistd.h內拷貝出來,對於組合語言有興趣的可以參考參考資料的連結

簡單從sections觀察一下



也是依序從a.out, b.out, tinytest,可以看到a.out sections最多,然後b.out的一些.data等最大,顯然引入很多"不必要"的資訊,最後tinytest相對section跟section size小很多,如果有興趣可以再去研究symbol table可以得到更多的答案,但就此打住吧。
我想有人會想問,還可以更小嗎?答案是可以的,至少把.comment這個section去除,就可以省下不少空間,也可以把.strtab ...等的section除去,還可以進步縮小,但這些大多只有在小程式有用,或者在極度記憶體限制下才來的必須。畢竟現在開發時間、移植性以及電腦速度大多遠大於我們對於performance以及optimization的過度追求,但也不表示程式能放棄品質於不顧,隨意寫出O(n^k)這樣的code(k>=2)

參考資料
http://c9s.blogspot.com/2008/06/linux-gnu-as-1.html

沒有留言:

張貼留言