明らかなことは別として (-Os -s
)、関数をクラッシュしない最小の値に調整すると(ARMの調整要件はわかりません)、関数ごとに数バイトが圧迫される可能性があります。
-Os
すべき すでに整列機能を無効にしていますが、これはまだデフォルトで 4 や 8 などの値になっている可能性があります。 to 1 は ARM で可能で、数バイト節約できます。
-ffast-math
(または研磨の少ない -fno-math-errno
) は errno を設定せず、いくつかのチェックを回避するため、コード サイズが削減されます。ほとんどの人と同じように、とにかく errno を読まない場合、それはオプションです。
__restrict
を適切に使用する (または restrict
) と const
冗長なロードを取り除き、コードをより速く、より小さく (そしてより正確に) します。純粋な関数をそのように適切にマークすると、関数呼び出しが排除されます。
LTO を有効にすると役立つ場合があります。それが利用できない場合は、すべてのソース ファイルを一度にバイナリにコンパイルします (gcc foo.c bar.c baz.c -o program
foo.c
をコンパイルする代わりに 、 bar.c
、および baz.c
最初にオブジェクトファイルにリンクしてからリンクする)と同様の効果があります。オプティマイザが一度にすべてを可視化できるため、より適切に機能する可能性があります。
-fdelete-null-pointer-checks
オプションの場合があります (これは通常、任意の "O" で有効になりますが、無効 であることに注意してください 埋め込みターゲット)
静的グローバル (あまり多くないことを願っていますが、それでも) を構造体に配置すると、多くのオーバーヘッドを排除できます。 それらを初期化しています。初めて OpenGL ローダーを作成したときに、そのことを知りました。構造体にすべての関数ポインターを持ち、構造体を = {}
で初期化する memset
への 1 つの呼び出しを生成します 、一方、「通常の方法」でポインターを初期化すると、それぞれを個別にゼロに設定するためだけに 100 キロバイトのコードが生成されます。
非自明なコンストラクタの static local を避ける 悪魔のような変数 (POD タイプは問題ありません)。 -fno-threadsafe-statics
でコンパイルしない限り、Gcc は非自明なコンストラクターの静的ローカル スレッドセーフを初期化します。 、たくさんリンクしています (スレッドをまったく使用しない場合でも) 余分なコードはありません。
通常の crt の代わりに libowfat のようなものを使用すると、大きく バイナリ サイズを小さくしてください。
バイナリから最後の一滴までスペースを絞り出したい場合は、おそらくアセンブリを学習する必要があります。非常に興味深い (そして面白い) イントロについては、次のリンクを参照してください:
Linux 用の非常に小さな ELF 実行可能ファイルの作成に関する旋風チュートリアル
次も使用できます -nostartfiles
および/または -nodefaultlibs
または両方の組み合わせ -nostdlib
.標準の開始ファイルが必要ない場合は、独自の _start 関数を作成する必要があります。 oompf のこのスレッド (アーカイブ済み) も参照してください:
(ペリンの言葉を引用)
# man syscalls
# cat phat.cc
extern "C" void _start() {
asm("int $0x80" :: "a"(1), "b"(42));
}
# g++ -fno-exceptions -Os -c phat.cc
# objdump -d phat.o
phat.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: 53 push %rbx
1: b8 01 00 00 00 mov $0x1,%eax
6: bb 2a 00 00 00 mov $0x2a,%ebx
b: cd 80 int $0x80
d: 5b pop %rbx
e: c3 retq
# ld -nostdlib -nostartfiles phat.o -o phat
# sstrip phat
# ls -l phat
-rwxr-xr-x 1 tbp src 294 2007-04-11 22:47 phat
# ./phat; echo $?
42
要約:上記のスニペットは 294 バイト のバイナリを生成しました 、各バイト 8 ビット。
別のツールも許可されていると仮定します;-)
次に、UPX を検討してください。これは、ランタイム解凍を使用するバイナリ用の究極のパッカーです。
コーディングをお楽しみください。