Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: progmetal в Aug 12, 2009, 10:10



Титла: Най-малък изпълним файл на програмата Hello World на C
Публикувано от: progmetal в Aug 12, 2009, 10:10
Покрай един курс във ФМИ се зарибих да видя докъде мога да орежа изпълнимия файл на проста програмка като Hello World на езика C. Написах следния сорс:
Код
GeSHi (C):
  1. #include<stdio.h>
  2. int main()
  3. {
  4.   printf("Hello World!\n");
  5.   return 0;
  6. }
Компилирах с
Код
GeSHi (Bash):
  1. gcc hello1.c -Os -o hello

и се получи следния резултат

Код
GeSHi (Bash):
  1. progrock ~/Programming/tests  $  ls -l hello
  2. -rwxr-xr-x 1 progrock users 4646 12 авг  9,43 hello
  3. progrock ~/Programming/tests  $  file hello
  4. hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

Ползвах strip и
Код
GeSHi (Bash):
  1. progrock ~/Programming/tests  $  strip -R .note -R .comment hello
  2. progrock ~/Programming/tests  $  ls -l hello
  3. -rwxr-xr-x 1 progrock users 2688 12 авг  9,56 hello
Размерът на изпълнимия файл намаля с близо 2000 байта, но все пак 2688 байта за програма от 72 байта ми се видя доста. Инсталирах си dietlibc и промених малко сорса като използвах системния примитив write:
Код
GeSHi (C):
  1. #include<unistd.h>
  2. int main()
  3. {
  4. write(1,"Hello World!\n",13);
  5. return 0;
  6. }
След същата процедура се получи абсолютно същия размер - 2688 байта.
Но след:
Код
GeSHi (Bash):
  1. progrock ~/Programming/tests  $  diet -Os gcc -Os hello2.c -o hello
  2. progrock ~/Programming/tests  $  strip -R .note -R .comment hello
се получи
Код
GeSHi (Bash):
  1. progrock ~/Programming/tests  $  file hello
  2. hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
  3. progrock ~/Programming/tests  $  ls -l hello
  4. -rwxr-xr-x 1 progrock users 1020 12 авг 10,04 hello

Обърнете внимание на statically linked - статично компилирано с glibc се получава над 500KB  ::)
Тестовете бяха проведени с GCC 4.4.1, dietlibc 0.32, glibc 2.10.1
Ако някой получи по-добри резултати да си каже  :) (чувал съм, че може да се получи към 500-600 байта статично binary на подобна програма на C)


Титла: Re: Най-малък изпълним файл на програмата Hello World на C
Публикувано от: gat3way в Aug 12, 2009, 18:38
Код:
[root@localhost tmp]# cat tst.c 
void __libc_csu_init(){}
void __libc_csu_fini(){}
void __libc_start_main()
{
char *hello="Hello world\n";
asm    ("mov $0x04, %%eax\n"
"mov %0, %%ecx\n"
"mov $0x1,%%ebx\n"
"mov $13, %%edx\n"
"int $0x80;"
"mov $0x1, %%eax\n"
"int $0x80"
:
: "r"(hello)
: "eax", "ecx", "ebx", "edx", "eax"
);

}
void main(){
};

[root@localhost tmp]# strip -R .init  ./tst
[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 1824 2009-08-12 18:32 ./tst
[root@localhost tmp]# ./tst
Hello world
[root@localhost tmp]# strip -R .strtab -R .symtab -R .bss -R .comment ./tst

[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 1460 2009-08-12 18:32 ./tst

[root@localhost tmp]# strip -R .data -R .got -R .got.plt -R .jcr ./tst
[root@localhost tmp]# ./tst
Hello world
[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 1248 2009-08-12 18:33 ./tst
[root@localhost tmp]# strip -R .dtors -R .ctors -R .eh_frame -R .fini ./tst
BFD: ./tst: warning: Empty loadable segment detected, is this intentional ?


[root@localhost tmp]# readelf ./tst -S
There are 6 section headers, starting at offset 0x31c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .note.ABI-tag     NOTE            080480b4 0000b4 000020 00   A  0   0  4
  [ 2] .note.gnu.build-i NOTE            080480d4 0000d4 000024 00   A  0   0  4
  [ 3] .text             PROGBITS        08048130 000130 00017c 00  AX  0   0 16
  [ 4] .rodata           PROGBITS        080482c8 0002c8 000019 00   A  0   0  4
  [ 5] .shstrtab         STRTAB          00000000 0002e1 00003a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
[root@localhost tmp]# strip -R .note.ABI-tag -R .shstrtab ./tst
BFD: ./tst: warning: Empty loadable segment detected, is this intentional ?

[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 984 2009-08-12 18:34 ./tst
[root@localhost tmp]# ./tst
Hello world
[root@localhost tmp]#


984 байта, ама това е голяма клизма. С малко inline assembly, с моя си инициализация и без финализиращ код. Въпреки което както се вижда работи :)


Титла: Re: Най-малък изпълним файл на програмата Hello World на C
Публикувано от: gat3way в Aug 12, 2009, 18:57
А, не съм пейстнал как се компилира:

cc -o tst  -nodefaultlibs -static tst.c


Титла: Re: Най-малък изпълним файл на програмата Hello World на C
Публикувано от: progmetal в Aug 12, 2009, 20:02
Благодаря за опциите на strip  [_]3

Код
GeSHi (Bash):
  1. progrock ~/Programming/tests  $  strip -R .data -R .got -R .got.plt hello
  2. progrock ~/Programming/tests  $  ./hello
  3. Hello World!
  4. progrock ~/Programming/tests  $  ls -l hello
  5. -rwxr-xr-x 1 progrock users 964 12 авг 20,01 hello

964 байта. Според мен може и още  ;D


Титла: Re: Най-малък изпълним файл на програмата Hello World на C
Публикувано от: Invincible в Aug 12, 2009, 22:44
Това ми напомня за Еволюцията на програмиста. http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html ($2)