1. ホーム
  2. c

[解決済み] なぜ.bssセグメントが必要なのですか?

2022-04-28 09:31:11

質問事項

私が知っているのは、グローバル変数とスタティック変数が .data セグメント、そして初期化されていないデータは .bss セグメントを使用します。私が理解できないのは、なぜ未初期化の変数に専用のセグメントがあるのか、ということです。 初期化されていない変数に実行時に値が割り当てられた場合、その変数はまだ .bss セグメントのみですか?

以下のプログラムでは a.data セグメントと b.bss ということでよろしいでしょうか?私の理解が間違っているならば、訂正してください。

#include <stdio.h>
#include <stdlib.h>

int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
int b[20]; /* Uninitialized, so in the .bss and will not occupy space for 20 * sizeof (int) */

int main ()
{
   ;
}  

また、次のようなプログラムも考えてみましょう。

#include <stdio.h>
#include <stdlib.h>
int var[10];  /* Uninitialized so in .bss */
int main ()
{
   var[0] = 20  /* **Initialized, where this 'var' will be ?** */
}

解決方法は?

理由は、プログラムサイズを小さくするためです。あなたの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に格納されているところです。もしワンセグだったら、ROMを大量のゼロで埋めなければならず、ROMサイズが大幅に増加する。

RAMベースの実行ファイルも、もちろん本当のROMは持っていませんが、同じように動作します。

また、memsetは非常に効率的なインラインアセンブラである可能性が高く、起動時のコピーダウンがより高速に実行できることを意味しています。