C言語 データ領域(.data)とBSS領域(.bss)の違いとは?初期値・ROM/RAM・起動処理まで実務目線で解説

目次

データ領域(.data)とBSS領域(.bss)の概要

まず結論です。

✔ .data → 初期値あり(ROMに保存 → 起動時にRAMへコピー)
✔ .bss → 初期値なし(起動時にゼロクリア)

この「初期値の有無」が、すべての違いの本質です。

そしてそれが「ROM使用量」に直結します。

項目データ領域(.data)BSS領域(.bss)
初期値ありなし
RAM配置されるされる
ROM保存するしない
起動処理コピーゼロクリア
主な影響ROM消費RAM消費

どちらも実行時にはRAMに配置されますが、
.dataは「ROMからコピー」、.bssは「ゼロクリア」で初期化されます。

本記事では、この違いを**実務目線(ROM/RAM・起動処理)で分かりやすく解説**します。

※.dataと.bssが分かれている理由は「ROM削減」と「起動処理の効率化」です。

メモリ領域解説シリーズ

本記事は「メモリ領域解説」シリーズの1つです。

メモリ領域解説シリーズの全体像はこちら

全体像(ROMとRAMの関係)

組み込み開発でメモリレイアウトを理解するうえで避けて通れないのが「データ領域」と「BSS領域」です。

データ領域とBSS領域は、どちらも最終的にはRAMに配置されます。

まずは全体像をイメージで見てみましょう。

メモリ領域は大きく「.text / .data / .bss / .rodata」などに分かれています。

メモリ領域の全体像

どちらもRAMに配置されるグローバル変数の領域ですが、役割はまったく異なります。

この記事では、

  • データ領域(.data)とは何か
  • BSS領域(.bss)とは何か
  • なぜわざわざ分かれているのか
  • 実務でどこを見るべきか

を、起動処理レベルまで踏み込んで解説します。

データ領域とBSS領域を含むメモリ領域の全体像についてはこちらの記事で解説しています。

初心者さん

.data領域と.bss領域って、どちらもグローバル変数が入る領域ですよね?何が違うんですか?

エンジニアくん

一番大きな違いは、初期値があるかどうかなんだ。
初期値がある変数は.data領域、 ない変数は .bss領域 に配置されるよ。

初心者さん

え、それだけなんですか?

エンジニアくん

実はそれが、ROMとRAMの使い方にも関わる重要な違いなんだ。


データ領域(.data)とは

データ領域とは、初期値を持つグローバル変数やstatic変数が配置される領域です。

int counter = 10;
static int flag = 1;

これらはデータ領域に配置されます。

static変数についてはこちらの記事で解説しています。

重要ポイント

  • 実行時はRAMに存在する
  • しかし初期値はROMに保存されている
  • 起動時にROMからRAMへコピーされる

ここが非常に重要です。

マイコンは電源投入直後、RAMの内容は保証されません。
そのため、ROMに保存された初期値をスタートアップコードがRAMへコピーします。

データ領域は起動時に初期値コピーされる

つまりデータ領域は、

「RAMにあるが、初期値はROM由来」

という特徴を持ちます。

スタートアップコードについてはこちらで解説しています。


BSS領域(.bss)とは

BSS領域は、初期値を持たないグローバル変数やstatic変数が配置される領域です。

int buffer[1000];
static int status;

これらはBSS領域に配置されます。

BSSの特徴

  • 実行時はRAMに存在
  • ROMに初期値データを持たない
  • 起動時にゼロクリアされる

スタートアップコードは、

BSS領域を0で初期化

という処理を行います。

BSS領域は起動時にゼロクリアされる

なぜデータ領域とBSS領域は分かれているのか?

ここが重要です。

理由① ROMを節約するため

BSS領域は「全部0」。

わざわざROMに0を保存する必要はありません。

もし分けなければ、

  • 1000要素の配列
  • すべて0

これをROMに格納することになります。

例えば

C
int buffer[1000];

これがすべて0だとしても、
もし.dataに入ると 1000個分の0がROMに保存されることになります。

BSS領域があることで、実行ファイルサイズを削減できます。


理由② 起動処理を最適化するため

データ領域 → コピー処理
BSS領域 → memset(0)

処理を分けることで、初期化が効率化されます。


理由③ メモリ使用量を明確にするため


データ領域はリンカやマップファイル上では「.dataセクション」と表示されることがあります。

同様にBSS領域はリンカやマップファイル上では「.bssセクション」と表示されることがあります。

マップファイルを見ると、次のように表示されます。

.data   0x20000000   0x120
.bss    0x20000120   0x300

これにより、

  • ROM消費量(.data初期値分)
  • RAM消費量(.data + .bss)

を分けて把握できます。

メモリマップについてはこちらの記事で解説しています。

またリンカスクリプトについてはこちらの記事で解説しています。


.rodata領域とは(補足)

ここまでで、.dataと.bssの違いは理解できたと思います。

実はもう1つ、重要な領域があります。

👉 **.rodata(読み取り専用データ領域)**です。


初心者さん

.rodataって初めて聞きました…

エンジニアくん

constが関係してきます!


const変数はどこに入る?

C
const int value = 10;

このような 書き換え不可(const)な変数は、多くの場合

👉 .rodata領域(読み取り専用領域)

に配置されます。

constの使い方についてはこちらの記事で解説しています。


.rodataの特徴

  • 書き換え不可(Read Only)
  • ROM(またはFlash)に配置されることが多い
  • RAMを消費しない場合がある

.data / .bss / .rodata の違い

領域初期値書き換え主な配置
.dataありRAM(初期値はROM)
.bssなしRAM
.rodataあり不可ROM

👉 まとめると

  • 書き換えたい → .data / .bss
  • 書き換えない → .rodata

注意点(実務)

コンパイラや設定によっては、

  • constでもRAMに配置される場合
  • 最適化で配置が変わる場合

があります。

👉 「必ず.rodataに入る」とは限らない

.rodataの詳細はこちらの記事で解説しています。

どの変数がどこに入る?(まとめ)

ここ、実務でめちゃくちゃ重要です。

C
int a = 10;         // .data
int b;              // .bss
static int c;       // .bss
static int d = 5;   // .data

constはどこに行く?

C
const int e = 10;

👉 多くの場合 .rodata(読み取り専用領域)


👉 まとめ

変数配置
初期値あり.data
初期値なし.bss
const.rodata

実務で注意すべきポイント

① データ領域が増えるとROMが不足する

初期値を大量に持つと、
ROM使用量が一気に増えます。

② BSS領域が増えるとRAM不足になる

大きなバッファを定義すると、
RAMを圧迫します。

③ 「意図せずデータ領域に入る」ケース

int buffer[1000] = {0};

これはBSS領域ではなくデータ領域になります。

なぜなら「初期値あり」だからです。

この違いはRAM/ROM両方に効きます。

よくある誤解:= {0} は BSS 領域ではない

初期値が 0 の場合、BSS領域に入ると思われがちですが、
明示的に = {0} と書いた場合でも、
データ領域に配置される場合と、BSS領域に配置される場合があります。
これはコンパイラや最適化設定に依存します。

int buffer1[1000];

これは初期値なしのため BSS領域 に配置され、
起動時にゼロクリアされます。

int buffer2[1000] = {0};

こちらは初期値ありとみなされ、データ領域に配置される場合があります。
ROMに初期値が保存され、起動時にRAMへコピーされます。

記述配置領域ROM使用初期化方法
int buf[1000];BSS領域使わないゼロクリア
int buf[1000] = {0};データ領域の場合あり使うROMからコピー

ただし、これは 必ずしも避けるべきではありません。

例えば次のようなケースでは、明示的に書いた方が可読性が高くなります。

  • 初期値 0 であることを明確にしたい
  • コード規約で初期化を必須としている
  • 意図しない未初期化を防ぎたい

つまり、

可読性を優先 → = {0}
ROM削減を優先 → 初期値を書かない

という判断になります。

組み込み開発ではメモリ制約が厳しいため、
大きな配列では BSS領域を使う方が有利な場合が多いですが、
小さな変数では可読性を優先する設計も一般的です。

このように、データ領域とBSS領域の違いは単なる仕様ではなく、
メモリの仕組みや設計判断にも関わる重要なポイントです。


まとめ

項目データ領域BSS領域
初期値ありなし
RAM配置されるされる
ROM保存するしない
起動処理コピーゼロクリア
主な影響ROM消費RAM消費

データ領域とBSS領域を理解すると、

  • マップファイルが読める
  • メモリ不足の原因が追える
  • 組み込み開発の基礎が固まる

メモリ設計を意識する第一歩として、必ず押さえておきたいポイントです。

C言語学習におすすめの書籍

新・明解C言語 入門編

data領域やbss領域を理解するには、
C言語の変数やメモリの基礎理解が重要です。

この書籍は、

  • static変数
  • グローバル変数
  • 配列
  • ポインタ

などを図やサンプルコードを使いながら丁寧に学べます。

「変数がどこに配置されるのか」をイメージしながら理解したい方におすすめです。

この記事が参考になった方へ

メモリ領域については他の記事でも解説しています。

またデータ領域とBSS領域の配置にかかわるC言語の文法についても当サイトでは解説しています。

エンジニアとして技術を学ぶことは重要ですが、
キャリアや副業についても同時に考える必要があります。

副業の現実や市場価値、今後のキャリア戦略については、
こちらの記事でまとめています。

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

組み込みソフトエンジニアとして働きながら、
C言語・メモリ・ポインタなどの基礎から実務まで解説しています。

副業・キャリアについても実体験ベースで発信中です。

X・Qiita・noteでも発信しています。
X:更新情報・日常
Qiita:技術発信
note:キャリア・副業

▼まずはここから読むのがおすすめ
C言語文法シリーズ
メモリ領域解説シリーズ
割り込み処理解説シリーズ
ソフトウェア設計解説シリーズ
キャリアと副業ロードマップ

コメント

コメントする


目次