仮想アドレス空間図

仮想アドレス空間の割り当ては、システム環境に関連しています。
次の図は、LinuxX86環境を示しています。

仮想アドレス
ここに画像の説明を挿入

* 1.予約領域(保護アドレス)

予約領域は、仮想アドレス空間の最下部に位置するサイズ0〜4Kの保護アドレスであり、物理アドレスは割り当てられていません(メモリアドレスに対応しないため、コンテンツは配置されません)。 )。それへの参照はすべて違法であり、メモリを参照するためにnullポインタと小さな整数値のポインタを使用する例外をキャッチするために使用されます。ほとんどのオペレーティングシステムでは、通常、NULLなどの非常に小さいアドレスへのアクセスは許可されていません。

通常の状況では、有効でアクセス可能なデータはアドレス0に格納されないため、C言語はこの理由で無効なポインタを0に割り当てます。ポインタを0に割り当てると、そのポインタは使用されない
ため、ワイルドポインタはありません。
#define NULL0と#defineNULL(void
)0はC言語では同等ですが、C ++では
#defineNULL 0しか使用できず、後で#define NULL(void
)0を使用すると間違いが発生します。
****

2.コードスニペット

コードセグメントは、本文セグメントまたはテキストセグメントとも呼ばれ、通常、プログラム実行コード(つまり、CPUによって実行されるマシン命令)を格納するために使用されます。通常、C言語の実行ステートメントは、マシンコードにコンパイルされ、コードセグメントに格納されます。通常、コードセグメントは共有可能であるため、頻繁に実行されるプログラムは、メモリにコピーを保持するだけで済みます。コードセグメントは通常、他のプログラムが誤って命令を変更するのを防ぐために読み取り専用です(このセグメントに書き込むとセグメンテーション違反が発生します)。一部のアーキテクチャでは、コードセグメントを書き込み可能にすることもできます。これは、プログラムを変更できることを意味します。

3.データセクション(.dataセクション)

データセグメントは通常、初期化されたグローバル変数と静的ローカル変数をプログラムに格納するために使用されます。データセグメントは静的メモリ割り当て(静的ス​​トレージ領域)に属し、読み取りと書き込みが可能です。グローバル変数の初期化されていないときのデフォルト値は0であるため、値が0のグローバル変数は(データセクションではなく).bbsセクションにあります。初期化されていないローカル変数の場合、それらの値は予測できません。注:コードセクションとデータセクションの間には、読み取り専用データセクションとシンボルセクションという他のセクションがあります。

4 ... bbsセグメント

このセクションは、値が0のグローバル変数を含む、初期化されていないグローバル変数と静的ローカル変数を格納するために使用されます。データセグメントと.bbsセグメントはグローバルデータエリアとも呼ばれ、前者は初期化され、後者は初期化されません。
ELFセクションには、コードセクション、その他のセクション(読み取り専用データセクション、シンボルセクションなど)、. dataセクション(データセクション)、および.bbsセクションが含まれ、これらはすべて実行可能プログラム部分に属します。

5.ヒープスペース

new()関数とmalloc()関数によって割り当てられたスペースは、メモリスペースの割り当てに使用されるペアスペースに下から上に属します。ヒープは、プロセスの実行中に動的に割り当てられたメモリセグメントを格納するために使用され、動的に拡張または縮小できます。ヒープの内容は匿名であり、名前で直接アクセスすることはできませんが、ポインターを介して間接的にのみアクセスできます。プロセスがmalloc©およびnew(C ++)関数を呼び出してメモリを割り当てると、新しく割り当てられたメモリがヒープに動的に追加されます(拡張)。free©/ delete(C ++)が呼び出されてメモリが解放されると、解放されたメモリが削除されます。ヒープから中程度の除去(削減)。

6.メモリマップドセグメント(共有ライブラリ)

ここで、カーネルはハードディスクファイルの内容をメモリに直接マッピングし、どのアプリケーションもLinuxのmmap()システムコールを介してこのマッピングを要求できます。メモリマッピングはファイルI / Oの便利で効率的な方法であるため、動的共有ライブラリをロードするために使用されます。たとえば、C標準ライブラリ関数(fread、fwrite、fopenなど)およびLinuxシステムI / O関数は、すべて動的ライブラリ関数であり、C標準ライブラリ関数は/lib/libc.soライブラリファイルにカプセル化されています。 、両方のバイナリファイル。これらのダイナミックライブラリ関数はすべて位置に依存しないコードです。つまり、メモリマッピング領域にロードされるたびに位置が異なるため、独自の論理アドレスを使用して線形アドレス(仮想アドレス)に変換します。次にマップします。メモリに。静的ライブラリは異なります。静的ライブラリは実行可能ファイルにリンクされているため、コードセグメントに配置され、アドレス空間での位置は毎回固定されます

7.スタックスペース

ストレージスペースを割り当てるときに、ローカル変数(C言語では自動変数と呼ばれる非静的ローカル変数)を上から下に格納するために使用されます。スタックとヒープはどちらも後入れ先出しのデータ構造です。

8.コマンドラインパラメータ

このセクションは、コマンドラインパラメーターargcおよびargvの内容を格納するために使用されます。

9.環境変数

現在の環境変数を格納するために使用され、Linuxでenvコマンドを使用してそれらの値を表示できます。

10.仮想アドレス空間の役割(利点)

1.コンパイラとオペレーティングシステムがプログラムのアドレスを調整します。2。各プロセスが独自の仮想アドレス空間に対応しているため、相互に干渉することなく各プロセスの空間間の分離を実現すると便利です。3。仮想を実現します。ストレージ、論理的に拡張されたメモリ。

追加する:

コードセグメント(.textセグメント)、読み取り専用データセグメント、シンボルセグメント(.rodataセグメント)はすべて読み取り専用の部分です。リンクすると、2つの部分が全体にリンクされますが、.dataはおよび.bbsセグメントRWの読み取り可能および書き込み可能な部分に属します。これらの4つの部分は、ページの形式でメモリに保存されます(1ページあたり4KB)。プロセス制御ブロックPCB(プロセス記述子とも呼ばれます)は、カーネル空間に配置されます。

転載元:https://blog.csdn.net/qq_33883085/article/details/88430087

おすすめ

転載: blog.csdn.net/weixin_52270223/article/details/115125675