その理由は、プログラムのサイズを小さくするためです。 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 ではなくセグメント セグメントですが、実行中のプログラムの動作には影響しません。