Tuesday, March 2, 2010

Hello World - 更小code size(3)






由上面兩圖可知,Hello World程式用printf()跟write()之差別,Hello World字串的輸出可以用write()取代,而不需要使用上libc的函式庫。

接下來...剩下程式的進入點、離開點的處理。



進入點的觀察:
到目前為止(包括上兩張圖)並未解釋如何知道通常一般應用程式的進入點是_start(而C語言的進入點是main)?
最簡單的方式...

$ cat helloworld.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define HELLO_WORLD "Hello World\n"

int main(void)
{
write(STDOUT_FILENO, HELLO_WORLD, sizeof(HELLO_WORLD));

return 0;
}

$ gcc -nostartfiles helloworld.c -o helloworld
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080481a4
$

於編譯中加入-nostartfiles的參數,將編譯時不需要額外的"起跑"程式段,直接呼叫main() function,會有警告訊息,找不到預設的程式進入點(_start),就是它啦.... _start是一個程式的進入點。

當然,這編譯出來的程式也可以執行只是會有問題(注意:是用動態連結方式編譯)...

$ gcc -nostartfiles helloworld.c -o helloworld
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080480c0
$ ./helloworld
程式記憶體區段錯誤
$

程式離開(執行return)時發生問題,所以改成...

$ cat helloworld.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define HELLO_WORLD "Hello World\n"

int main(void)
{
write(STDOUT_FILENO, HELLO_WORLD, sizeof(HELLO_WORLD));

exit(0);

return 0;
}

$ gcc -nostartfiles helloworld.c -o helloworld
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080481d8
$
$ ./helloworld
Hello World
$

來看看它的code size...

$ gcc helloworld.c -o helloworld.normal -O3
$ strip helloworld.normal
$ gcc helloworld.c -o helloworld.nostartfiles -O3 -nostartfiles
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080481d8
$ strip helloworld.nostartfiles
$ ls -l
總計 12
-rw-r--r-- 1 lungswu lungswu 206 2010-02-26 13:57 helloworld.c
-rwxr-xr-x 1 lungswu lungswu 2928 2010-02-26 14:02 helloworld.normal
-rwxr-xr-x 1 lungswu lungswu 1484 2010-02-26 14:02 helloworld.nostartfiles

code size又減小了(變成1484 bytes)

No comments:

Post a Comment