Keil、IAR コンパイル (ビルド) ウィンドウに出力される情報:
プログラムサイズ: コード=2596 RO-データ=268 RW-データ=44 ZI-データ=1028
72765 バイトの読み取り専用コード メモリ
3508バイトの読み取り専用データメモリ
20202 バイトの読み書きデータ メモリ
5676 バイトの CODE メモリ
926バイトのCONSTメモリ
1148バイトのDATAメモリ
誰もが上記の情報を見たことがあり、その一般的な意味を知っているはずだと思いますが、ストレージの詳細を深く理解している友人はどれくらいいますか?
コード、定数、グローバル変数、およびローカル変数がどこに保存されているかを知るには、FLASH と RAM のいくつかの特性を理解する必要があります。プロジェクトでは、それらのサイズと対応するストレージ アドレスを分析する必要があります。これらはマップ ファイルから分析できます。 。
ほとんどの人に気を配るために、上記の印刷情報の意味について簡単に話してください。ここで皆さんに思い出していただきたいのですが、インターネット上には関連情報がたくさんありますが、インターネット上の情報の多くは曖昧で、次のような誤解を招く可能性があります。 RW-data は初期化されたグローバル変数です。static で変更された変数は静的変数と呼ばれ、グローバル変数とは異なりますが、初期化された静的変数も RW-data に含まれます。
1.Keilコンパイルウィンドウ情報
プログラムサイズ: コード=2596 RO-データ=268 RW-データ=44 ZI-データ=1028
コード: コードのサイズを指します。
Ro-data: インラインデータ以外の定数データを指します。
RW データ: 読み取りおよび書き込み可能 (RW) の初期化された変数データを指します。
ZI データ: 初期化されていない (ZI) 変数データを指します。
コード、Ro-data: FLASH にあります。
RW データ、ZI データ: RAM にあります。
注意: RWデータの初期化されたデータはフラッシュに保存され、電源投入時にフラッシュからRAMに移動されます。
関係は次のとおりです。
RO サイズ = コード + RO データ
RW サイズ = RW データ + ZI データ
ROM サイズ = コード + RO データ + RW データ
2. IAR コンパイルウィンドウの情報
IAR には 2 つの状況がありますが、意味は似ていますが、表示が異なります。
プロジェクトをコンパイルすると (「作成」をクリック)、次の情報が表示されます。
72,765バイトの読み取り専用コードメモリ
3 508 バイトの読み取り専用データ メモリ
20 202 バイトの読み書きデータ メモリ
単一のファイルをコンパイルすると ([コンパイル] をクリック)、次の情報が表示されます (DATA がない場合は、行は表示されません)。
5 676 バイトの CODE メモリ
926バイトのCONSTメモリ
1 148バイトのDATAメモリ
読み取り専用コード: コード サイズ (CODE と同様)。
読み取り専用データ: 定数データ (CONST と同様)。
readwrite data: 変数データは読み取りおよび書き込みが可能です (DATA と同様)。
例証します:
IAR のデータは Keil の RW データ + ZI データと同等です
メモリ (RAM) の割り当て
このセクションでは、プログラムの実行時の RAM の状況を理解するのに役立つ、RAM に関する知識を深めます。
記憶は 5 つのカテゴリに分類されます。
1. スタック領域(スタック):コンパイラによって自動的に確保・解放され、関数のパラメータ値やローカル変数の値などが格納されます。
2. ヒープ領域(heap):通常、プログラマによって確保(malloc)、解放(free)されますが、プログラマが解放しないと常に占有されます。一般に、MCU プログラムは通常、ヒープを使用しません。
3. グローバル領域(静的領域)(静的):グローバル変数と静的変数は一緒に格納され、初期化されたグローバル変数と静的変数は同じ領域にあり、初期化されていないグローバル変数と初期化されていない静的変数は別の領域に隣接しています。
4. リテラル定数領域 (const): 定数文字列がここに配置されます。
5. プログラムコード領域(コード):関数本体のバイナリコードを格納します。
典型的な例:
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main(void)
{
int b;// 栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; 123456\0";//在常量区,p3在栈上。
static int c =0; //全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}