前処理ソースの.cppギブ
前処理からコンパイル.Iファイル
アセンブリファイルのコンパイルを取得します.S
リンクオブジェクトファイルを取得するの.o
実行可能ファイル
例:main.cppにはfun.cppのfun.h
1の#include <iostreamの> 2の#include " fun.h " 3 使用 名前空間STDを、 4 5 の#define PI 3.14 6 7 INT メイン() 8 { 9 プリント()。 10 coutの<< PI << てendl; 11 リターン 0 ; 12 }
1 #ifndefの_FUN_H_ 2 の#define _FUN_H_ 3 ボイドプリント(); 4 #endifの
1の#include <iostreamの> 2の#include " fun.h " 3 4 ボイドプリント() 5 { 6 のstd :: COUT << 、 " こんにちは、世界" << はstd :: ENDL。 7 }
1.前処理
G ++ -E main.cppに-o main.i
main.i、fun.i:
前記ソース処理ディレクティブ、および特殊記号(#命令が始まる)の
(1)マクロ定義命令
main.cppにに#define PI 3.14を持っているとして、前処理の後に置き換えられました
(2)条件付きコンパイルディレクティブ
#IFDEF、IFNDEF#、#他に、#elifの、#endifのマクロ定義のように参照の重複を避けるために、処理され、どのようなコードに依存して決定
(3)ヘッダファイルは、命令を含みます
書式#include <xx.h>の#include "xx.h" 等
マクロ定義の多数のこれらのヘッダー
(4)特殊記号
1つのprintf(" 日付:%sの、時間:%sの、ファイル:%sの、ライン:%dの、のFunc:%sの\ nは"、__ DATE __、__ TIME __、__ FILE __、__ LINE __、__ FUNCTION__)。
前処理した後、結果の.iファイルがないマクロ定義、何の条件付きコンパイルディレクティブが存在しない、特別なシンボル
2.コンパイル
G ++ -S main.i -o main.S
G ++コンパイラによって、唯一のいくつかの数字、文字列やキーワードの定義を前処理した後のファイル:字句解析、構文解析、最適化、アセンブリファイルを生成します
3.コンパイル
アセンブリコードをマシン命令にコンパイル
4.リンク
複数の.oファイル、および実行可能ファイルにリンクされたライブラリファイル
ライブラリfun.o main.o -o a.outというのLDの束
G ++ -vが見る必要ライブラリmain.o
ファイルにcollect2は最終的なリンクを呼び出すことにより、G ++、collect2ははLDのパッケージです
(1)静的リンク
入力として再配置可能オブジェクトファイルおよびコマンドラインパラメータでは、完全なリンクを生成する実行可能なオブジェクト・ファイルをロードして実行することができます。
実行可能プログラムにコードリンクライブラリをコピーします
静的リンクは実行します。
①シンボル解決:リンクされたターゲット・ファイルシンボリック参照および定義(いくつかの他のシンボルが符号モジュールのように)
②移転:コンパイラ、アセンブラ、アドレス0から始まるコードデータを生成し、リンカー、及び各記号の定義メモリ位置リンク、次いで、すべての参照にこれらの記号を変更する、別の場所から開始し、このような。
(2)ダイナミックリンク
コンパイラは、渡されたことを保証するために、ターゲット・ファイル・ダイナミック・リンク・ライブラリまたは共有オブジェクト、リンクステージ、ダイナミック・リンク・ライブラリは、すべてのシンボリック参照が定義されていることを保証するために、そのようなシンボルテーブルとして情報の少量を提供する(静的に直接コピーされリンクされていない)で定義された関数、 。実行可能ファイルが実行されると、そのような仮想アドレス空間のようなダイナミックリンクライブラリ関数の内容は、実行中の対応する処理にマッピング。
(3)ターゲットファイル
①再配置可能なオブジェクトファイル:シンボルを参照するデータを含むバイナリコードは、他のモジュールで実行することができません
②共有オブジェクト/動的ライブラリ:の.soファイル
③実行ファイル
(4)ELFオブジェクトファイル形式のファイル
ELFヘッダ:システム記述ファイルワード長バイト順、ELFヘッダサイズ、ターゲット・ファイルの種類、ターゲットマシンのタイプ、等
.text:コードセグメント、実行可能バイナリマシン命令
.rodata:文字列定数などの保存された読み取り専用のデータセグメントを
.DATA:クリア初期化グローバルデータにデータセグメント(グローバル変数、静的変数)、スタティックメモリアロケーション
.bssの:ブロック記憶セグメント、明示的グローバルデータを初期化しない、グローバルデータを0に初期化され、静的メモリアロケーション
4つのセグメントは、上記メモリにロードされます
.symtab:シンボルテーブル、定義および参照関数とグローバル変数
.rel.text:リロケーション修飾シンボルに頼る概要スニペットの再配置に必要な情報、保管場所が必要
.rel.data:再配置情報のデータセグメント
.DEBUG:gccの-gオプションは、このセクションを生成し、
.LINE:マップをデバッグするためのソースコードの行番号
.strtab:名前の文字列テーブル記憶SYMTAB、シンボルテーブル内のデバッグシンボル
ELFファイルの内容、コマンドの各セグメントのサイズを表示します。
1 readelfが-aメイン
2サイズ主
gccのコマンドの基本的なオプション:
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------
ライブラリの生成と使用:
(1)静的ライブラリ
AR RCS fun.a fun1.o fun2.o
オプション:R:静的ライブラリのリストで、対象ファイルの追加
C:あなたが存在しない静的ライブラリを指定した場合は、ファイルを作成します
S:静的ターゲットファイルの新しい内容が含まれるように、インデックスファイルを更新
ときにリンク:
GCCのmain.c -lfun.a - メインO
gcc -L. main.c -o main
-L紧跟静态库路径
(2)动态库
gcc -shared -fPIC -o lib.so lib,c
选项的含义:
-shared:生成动态库
-fPIC:生成位置无关代码
链接时:
gcc main.c ./lib.so -o main
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
可执行文件在运行时:
除了代码段、数据段、BSS段,还有堆区和栈区
堆区:用于动态分配内存,用 malloc、free申请和释放
从低地址向高地址增长
链式存储
效率比栈低
栈区:由操作系统自动分配和释放,存储函数的参数值、局部变量的值等
从高地址向低地址增长
连续内存
最大容量固定