Ключевые слова:optimization, (найти похожие документы)
Date: Wed, 14 Mar 2001 19:52:19 +0000 (UTC)
From: yx <[email protected]>
Newsgroups: fido7.ru.unix
Subject: Борьба за уменьшения размера (до 300 байт!) программы "Hello,World"
> Вопpос вот возник. В эхе RU.PASCAL.MODULA.ADA вдpуг один товаpищ
> сообщил, что pазмеp статически собpанной сишной пpогpаммы
> с одним только выводом "Hello, World!" всего около 3 КБайтов.
> Это, случано, не деза?
>
можно и около 800 байт, можно и меньше..
% cat >mini_hello.c
#define MESG "Hello, World!\n"
#define MESG_SZ sizeof(MESG)
main() {
write(1,MESG,MESG_SZ);
_exit(0);
}
^D
% gcc -nostartfiles -nodefaultlibs -nostdlib -static -s -O99 -o mini_hello mini_hello.c -lc 2>/dev/null
%
% ./mini_hello
Hello, World!
%
% ls -l mini_hello
-rwxr-xr-x 1 yx users 840 Mar 14 21:28 mini_hello
% ldd mini_hello
not a dynamic executable
% gcc --version ; uname -sr
egcs-2.91.66
Linux 2.4.0-test1
p.s.
это на том что сейчас под рукой (на фак-те) и на скорую руку,
в домашних условиях еще меньше будет ,)
bye.
--
Vladimir Yakovetsky
----------------------------------------------------------------
From: yx <[email protected]>
>> Простите, но точку входа я могу написать свою. Минимальную. Которая будет
>> звать main(0,{""}). Почему эта программа не будет программой на языке *C*?
>
> а "точку входа" вы тоже на C писать будете? про курицу и яйцо сами
> вспомните?
>
>> Или gcc не позволяет указать custom entry point? Позволяет.
>
> gcc? нет, не позволяет.
1) gcc не компилятор (верней не только).
2) gcc - позволяет (позволяет передать кому надо точку входа).
можно так:
% cat start1.c
#define MESG "Hello, World!\n"
#define MESG_SZ sizeof(MESG)
main() {
long re;
__asm__ volatile (
"int $0x80": "=a"(re): "0"(4), "b"(1), "c"((long)MESG), "d"((long)(MESG_SZ))
);
__asm__ volatile (
"int $0x80": "=a"(re): "0"(1),"b" (0)
);
}
% gcc -nostartfiles -nodefaultlibs -nostdlib -static -o start1 start1.c -Wl,--entry=main && ./start1
Hello, World!
а можно и так:
% cat start2.c
#define MESG "Hello, World!\n"
#define MESG_SZ sizeof(MESG)
void _start() __asm__("_start");
/* void __attribute__((section(".init"))) _init() {} */
void _start() {
long re;
__asm__ volatile (
"int $0x80": "=a"(re): "0"(4), "b"(1), "c"((long)MESG), "d"((long)(MESG_SZ))
);
__asm__ volatile (
"int $0x80": "=a"(re): "0"(1),"b" (0)
);
}
% gcc -nostartfiles -nodefaultlibs -nostdlib -static -o start2 start2.c && ./start2 && ./start2
Hello, World!
и еще много как можно...
> какое дело компилятору до каких-то там точек входа.
>
компилятору непосредственно - никакого,
однако gcc - морда к: препроцессор,компилятор,ассемблер,линкер.
И линковка с standard system startup files - забота линкера.
bye.
--
Vladimir Yakovetsky
--------------------------------------------------------
From: yx <[email protected]>
[email protected] wrote:
>>> нет, вы привели два примера не-пойми-на-каком-языке-написанных,
>>> с которорыми не-понятно-что-делать.
>
> разговор о языке си.
>
хорошо о пчелах:
1) startup system files - не имеют отношения ни к си-компилеру, ни к самому cи
- следовательно "-nostartupfiles"
2) библиотеки вода/вывода никогда не были составляющей частью языка си:
- следовательно "-nodefaultlibs -nostdlib"
3) всякая ха-оптимизация не имеет прямого отн-я к си-синтаксису:
- следовательно "-O99 -fomit-frame-pointer -s -static -Wl,--gc-section"
4) стд си-синтаксис, а-не-какой-то-там-непонятно-что:
- тогда:
% cat > mini_hello.c
#include <unistd.h>
#include <linux/unistd.h>
_syscall3(ssize_t, write, int, fd, const void*, buf, size_t, count);
_syscall1(int, exit, int, status);
#define MESG "Hello, World!\n"
#define MESG_SZ sizeof(MESG)
int errno;
main() {
write(1,MESG,MESG_SZ);
exit(0);
}
^D
% gcc -nostartfiles -nodefaultlibs -nostdlib -s -static -O99 -fomit-frame-pointer -Wl,--entry=main,--gc-section -o mini_hello mini_hello.c 2>/dev/null && ./mini_hello
Hello, World!
%
% file mini_hello
mini_hello: ELF 32-bit LSB executable, Intel 80386, version 1, statically linked, stripped
%
% ls -l mini_hello
-rwxr-xr-x 1 yx users 568 Мар 20 06:13 mini_hello
Итого 568 байт (си соурс - по крайней мере синтаксис,)
если соурс.s через гнутые as/ld - аналог-й код даст байт ~350 (elf/x86)
(все тоже прогнанное через b(rute)cc, as86/ld86 - будет раза в полтора
меньше соот-но)
здесь системно-зависимы только сисколы, дергаемые мимо библио-х ф-й.
(анал-й код с исп-м glibc даст около ~750 байт)
все.
--
Vladimir Yakovetsky
-------------------------------------------------------------
From: yx <[email protected]>
Newsgroups: fido7.ru.unix
Subject: 2,5| minimalism linux/i386[email protected] wrote:
>>> угу. а crt0.o и сколько за собой тащит не считали? от 3 до 8 кб, в
>>> зависимости от юникса.
>>
>> под Win32, и я _не_верю_, что это так уж сложно сделать в *IX.
>
> затем, что именно в нём находится точка входа в ваше программу на языке C
> (crt0 - это C Run Time, не забывайте) - _main, а также start (или _start).
> без crt0.o вы не сможете создать программы на языке *C* - это будет что
> угодно, но только не программа на языке C.
>
минимализм linux/i386.
непосредственно си (280 байт):
% cat > hello_c.c
#define MESG "Hello, World!\n"
#define MESG_SZ sizeof(MESG)
void main() {
write(1,MESG,MESG_SZ);
}
^D
% bcc -N -3 -s -o hello_c hello_c.c && ./hello_c
Hello, World!
% file hello_c
hello_c: Linux/i386 impure executable (OMAGIC), stripped
% ls -l hello_c
-rwxr-xr-x 1 yx users 280 Mar 21 16:02 hello_c
% size hello_c
text data bss dec hex filename
196 52 4 252 fc hello_c
т.е. все равно много лишнего.
тогда дальше:
непосредственно asm (80 байт):
% cat > hello_s.s
use32
entry start
.text
start:
mov eax, *4
mov ebx, *1
mov ecx, #mesg
mov edx, *0xf
int 0x80
mov eax, *1
xor ebx, ebx
int 0x80
mesg:
.ascii "Hello, World!"
.byte 0xa, 0
end
^D
% as86 -o hello_s.o hello_s.s
% ld86 -s -N -o hello_s hello_s.o && ./hello_s
Hello, World!
% file hello_s
hello_s: Linux/i386 impure executable (OMAGIC), stripped
% ls -l hello_s
-rwxr-xr-x 1 yx users 80 Mar 21 16:08 hello_s
% size hello_s
text data bss dec hex filename
48 0 0 48 30 hello_s
почти ничего лишнего (кроме 32-x байтного заголовка,)).
итого "Hello, World!":
с (+crt,+libc) 280 байт
asm 80 байт
bye.
--
Vladimir Yakovetsky
Ловите 72 байта
# uname -a
Linux 2.6.12-rc5 i686 athlon i386 GNU/Linux
# as -v
GNU assembler version 2.15.94.0.2.2 (i586-suse-linux) using BFD version 2.15.94.0.2.2 20041220 (SuSE Linux)
# ld -v
GNU ld version 2.15.94.0.2.2 20041220 (SuSE Linux)