その理由は、プログラムのサイズを小さくするためです。 C プログラムが組み込みシステムで実行され、コードとすべての定数が真の ROM (フラッシュ メモリ) に保存されていると想像してください。このようなシステムでは、main() が呼び出される前に、最初の「コピーダウン」を実行して、すべての静的ストレージ期間オブジェクトを設定する必要があります。通常、次の擬似のようになります:
for(i=0; i<all_explicitly_initialized_objects; i++)
{
.data[i] = init_value[i];
}
memset(.bss,
0,
all_implicitly_initialized_objects);
.data と .bss は RAM に保存されますが、init_value は ROM に保存されます。それが 1 つのセグメントだった場合、ROM を多数のゼロで埋める必要があり、ROM サイズが大幅に増加しました。
もちろん、真の ROM はありませんが、RAM ベースの実行可能ファイルも同様に機能します。
また、memset は非常に効率的なインライン アセンブラーである可能性が高いため、起動時のコピーダウンをより高速に実行できます。
.bss
セグメントは最適化です。 .bss
全体 セグメントは、実行中のプロセスでのサイズを示す単一の数値 (おそらく 4 バイトまたは 8 バイト) で表されますが、.data
は section は、初期化された変数のサイズの合計と同じ大きさです。したがって、.bss
実行可能ファイルが小さくなり、読み込みが速くなります。それ以外の場合、変数は .data
にある可能性があります ゼロへの明示的な初期化を伴うセグメント。プログラムは違いを見分けるのに苦労するでしょう。 (詳しくは .bss
のオブジェクトのアドレス .data
にある場合は、おそらくアドレスとは異なるでしょう。 セグメント)
最初のプログラムでは a
.data
になります セグメントと b
.bss
になります 実行可能ファイルのセグメント。プログラムがロードされると、区別は重要ではなくなります。実行時、b
20 * sizeof(int)
を占めています バイト。
2 番目のプログラムでは、var
スペースが割り当てられ、main()
で割り当てられます そのスペースを変更します。 var
のスペースがたまたま .bss
に記述されていました .data
ではなくセグメント セグメントですが、実行中のプログラムの動作には影響しません。