1.仮想アドレス空間
悪意のあるプログラムが他のプログラムのメモリデータを変更しないように、プロセスアドレス空間を分離する必要があるため、仮想アドレス空間がコンピューターに導入されます。
仮想アドレス空間のレイアウト
.text(コードセグメント) | 実行可能コード、読み取り専用変数、文字列定数 |
---|---|
.data(データセグメント) | 初期化され、初期値が0ではないグローバル変数と静的変数(グローバルおよびローカル) |
.bss | 初期化されていないか、初期値が0のグローバル変数と静的変数。変数が初期化されると、bssセグメントがクリアされます |
ヒープ | 動的に割り当てられたメモリ |
共有ライブラリ | プログラムは、実行時に動的にメモリに読み込まれます(Linuxでは.soファイル、未亡人では.DLLファイル)。 |
スタック | プログラムの実行中、ここでデータ操作を実行し、一時データ(ローカル変数、ローカル読み取り専用変数、関数パラメーター、戻りアドレスなど)を格納し、関数スタックを開くなどする必要があります。Linuxでは、スタックは上位アドレスから下位アドレスに開かれます。関数スタックの場合、関数が完了するとメモリが解放されます。 |
コマンドラインパラメーター | ps -eLfと同様に、-eLfはコマンドラインパラメータであり、psは実行可能プログラムです。 |
環境変数 | LinuxでのPATHやHOMEなどの環境変数(子プロセスは親プロセスの環境変数を継承します) |
ZONE_DMA | 直接アクセスエリア、16M |
ZONE_NORMAL | 共通領域、マッピングページディレクトリテーブル、892M |
ハイメモリ領域 | 1Gより大きいファイルのマッピング |
2.コンパイルとリンクの原則
コンパイルとリンク:
1)プリコンパイル(* .iファイルを生成)
1>すべての「#define」を削除してすべてのマクロを展開します;
2>「#if」、「#ifdef」、「」などのすべての条件付きプリコンパイル命令を破棄します#elif "、" #else "、" #endif ";
3>再帰的なプロセスである" #include "命令を処理する;
4>すべてのコメントを削除する" // "と" / * * / ";
5>追加する行番号とファイル名の識別;
6> #pragmaコンパイラーのすべての命令をコンパイラーで使用するために予約します。
2)コンパイル(* .sファイルの生成)
前処理されたファイルは、一連の字句解析、構文解析、意味解析、および最適化の対象となり、対応するアセンブリコードファイルが生成されます。
3)アセンブリ(* .oファイルの生成、オブジェクトファイルとも呼ばれます)
アセンブラは、アセンブリコードをマシンが実行できる命令に変換します各アセンブリステートメントは、ほぼマシン命令に対応しています。
4)リンク(* .exeファイルを生成、実行可能ファイルとも呼ばれます)
1>アドレスとスペースの割り当て;
2>シンボル分析;
3>シンボルの再配置;
.oファイルの単純なファイル形式のレイアウト
。Bssはターゲットファイルのスペースを占有しません。ELF
ヘッダーにセクションヘッダーと呼ばれるセクションがあることがわかります。このセクションには、セクションのサイズなど、ターゲットファイルの各セクションの詳細情報が保存されます。オフセットとその他の情報を開始します。コンパイラは、このセクションにアクセスしている限り、各セクションの詳細情報を知ることができます。.bssはスペースを占有しませんが、.bssセクションの詳細情報はセクションヘッダーに格納され
ます。gdata3は.bssセクションに格納されていないことがわかります。このデータは、C言語の強いシンボルと弱いシンボルに関連するCOMブロックに格納されます。
ストロングシンボル:グローバル初期化シンボルウィークシンボル:グローバル未初期化シンボルストロングシンボルとウィークシンボルの選択規則:
1. 2つのストロングシンボルのコンパイルエラー
2. 1つのストロングシンボルと1つのウィークシンボルがストロングシンボルを選択します
3. 2つのウィークシンボルコンパイラごとに異なる処理方法
プロジェクトには複数のソースファイルがある場合があります。コンパイル段階では、各ファイルが個別にコンパイルされます。他のファイルには強いシンボルが含まれている可能性があるため、コンパイル中に特定のシンボルを特定する方法はありません。したがって、このファイルのウィークシンボルは、.bssセクションではなくCOMブロックに格納されます。
シンボルの解決とシンボルの再配置
シンボルの解決
各ファイルシンボルリファレンス(外部シンボルへの参照)でシンボルの定義を見つけます。これはシンボル解決です
シンボルの再配置
まず、リンクする前に生成されたアセンブリコードを確認します。
これらの2つの場所はそれぞれ0000です。0000は、リンクする前にコンパイラによってgdataに与えられるアドレスを表します。FFFF FF FCは、リンクする前にコンパイラによってSum関数に与えられる関数のエントリアドレスを表します。 。どちらのアドレスも無効です。リンク後にこれら2つのアドレスを確認してください。これら2つの
アドレスは、gdataの特定の仮想アドレスとSum関数の相対変位オフセットになります。シンボルのリダイレクトは、特定の仮想アドレスまたは相対変位オフセットを.oファイルの.textセクション命令の無効なアドレスに与えることです。
実行可能ファイルのヘッダー情報を見てみましょう
この時点で、このプログラムのエントリアドレスには080480A4が割り当てられています。これは、メイン関数のエントリアドレスです。これでプログラムを実行できます。