Source code如下...
1 /*
2 * File name : helloworld.c
3 */
4
5 #include <stdio.h>
6
7 int main(void)
8 {
9
10 printf("Hello World\n");
11
12 return 0;
13 }
14
用了以下四種不同的編譯參數以及其結果...
$ gcc helloworld.c -o helloworld
$ ls -l helloworld
-rwxr-xr-x 1 lungswu lungswu 6159 2010-02-24 22:57 helloworld
$
$ gcc helloworld.c -o helloworld -O3
$ ls -l helloworld
-rwxr-xr-x 1 lungswu lungswu 6141 2010-02-24 22:57 helloworld
$
$ gcc helloworld.c -o helloworld -static
$ ls -l helloworld
-rwxr-xr-x 1 lungswu lungswu 558138 2010-02-24 22:58 helloworld
$
$ gcc helloworld.c -o helloworld -static -O3
$ ls -l helloworld
-rwxr-xr-x 1 lungswu lungswu 558740 2010-02-24 22:58 helloworld
$
發現以上四種編譯方式中,使用"gcc helloworld.c -o helloworld -O3"的編譯方式可以產生最小的code size(總共6141 bytes)
但是有一點需注意:編譯的時候加入"-static",code size變的很大....
原因無它,這是因為一般程式在做連結/執行的時候,會需要用到額外標準函式庫,很明顯的此HelloWorld程式於執行時會連結標準函式庫(libc),且至少printf()此函數為libc之中的一函數。
一般程式於編譯時,會將這些標準函式庫的函式主體放於別的檔案,程式於執行時再由OS(loader)判斷,且適時載入記憶體之中供執行中程式呼叫使用,此種機制稱做為"動態聯結"(dynamically link)。
反之,若連結程式時將這些函數一起連結於程式之中,稱之為靜態連結(statically link),可以以-static指定為靜態連結。
由於靜態連結會將標準函式庫編入程式之中,所以程式大小會差很多,有558740/6141=91倍之多。
要如何判別一檔案是動態連結還是靜態連結,可以用UNIX下的一個command:"file"
$ gcc helloworld.c -o helloworld
$ file helloworld
helloworld: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
$
$
$ gcc helloworld.c -o helloworld -static
$ file helloworld
helloworld: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.8, not stripped
$
另外一個問題,要知道動態聯結的程式有用到哪些額外的函式庫?可以使用"ldd" command。
由以下的實做可以得知,執行檔"helloworld"會使用到"linux-gate.so.1","libc.so.6"以及"/lib/ld-linux.so.2"此三的動態函式庫。
$ ldd helloworld
linux-gate.so.1 => (0xb7fa2000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7e36000)
/lib/ld-linux.so.2 (0xb7fa3000)
$
No comments:
Post a Comment