Linux コンパイラ - gcc/g++ (前処理、コンパイル、アセンブル、リンク)

前書き:この記事は主に、環境内で一般的に使用されるコンパイラ - (コンパイルされたコード)/ (コンパイルされたコード) の共通命令など、プログラム実装のための 2 つの主要な環境、動的ライブラリと静的ライブラリの理解などを理解して学習します
LinuxgccCg++C++

1. プログラム実装のための 2 つの環境

プログラムを実現するには、翻訳環境実行環境Cを経由する必要があります

翻訳環境では、プリコンパイル、コンパイル、アセンブリ、リンクの4 つの部分に分かれています。各段階で完了する主なタスクは次のとおりです。

  1. プリコンパイル (前処理): ヘッダー ファイルのインクルード、コメントの削除、#define シンボルの置換
  2. コンパイル: C 言語コードをアセンブリ コードに変換します。
  3. アセンブリ: アセンブリ命令をバイナリ命令に変換します。
  4. リンク: シンボルテーブルとセグメントテーブルをマージして実行可能プログラムを生成

ここに画像の説明を挿入

2. gcc を完了する方法

各段階で形成されたファイルは、コマンドのさまざまなオプションを使用してgcc表示できます。

形式: gcc [オプション] [オブジェクトファイル名] -o [生成ファイル名]

まず、ファイルにコードをTest.c記述します。C

//Test.c
#include<stdio.h>
 
#define N 100
 
//这是一段注释.....
 
int main()
{
    
    
	int n = 0;
	printf("Hello World\n");
	printf("%d\n", n + N);
	return 0;
}

1. 前処理

Test.c前処理された結果を表示します。-Eこのオプションの機能は gcc、前処理の完了後にコンパイル プロセスを停止することです。-o機能は、前処理された内容を test.iファイルに保存することです。

gcc -E Test.c -o test.i

ここに画像の説明を挿入

図に示すように、前処理段階ではヘッダファイルの組み込み、コメントの削除、#defineの置換などが行われます。

2.コンパイル

次に、生成されたばかりの をコンパイルしtest.i、コンパイル後に停止し、結果を に書き込みますtest.sgcc使用されるオプションは次のとおりです -S

gcc -S test.i -o test.s

ここに画像の説明を挿入

私たちはアセンブリ言語を学んでいなくても、これらがアセンブリ コードであることを漠然と認識しており、コンパイル段階では C コードをアセンブリ命令に変換することがわかります。

3. 編集

gcc使用されたオプションは、 -c-o 結果を に書き込む」ですtest.o

gcc -c test.s -o test.o

ここに画像の説明を挿入
コンパイル完了後はご覧のとおりこのような文字化けが発生しています。実際、コンパイル後に生成されるファイルは、コンピュータに表示するために使用されるバイナリ ファイルであり、それを理解することはできません。

4.リンク

コンパイルが完了するとリンク段階に入り、リンク完了後に実行可能プログラムが生成されますtest

gcc test.o -o Test

ここに画像の説明を挿入

しかし、リンクの場合は、それが何にリンクしているのかを知る必要があります。
たとえば、関数が定義されていないのにprintfreturn... などの関数が使用できるのはなぜでしょうか。

実際には、システムはこれらの関数の実装をlibc.so.6という名前のライブラリ ファイルに入れます。特別な指定がなければ、gccシステムのデフォルトの検索パス
/usr/libで検索libc.so.6、つまりライブラリ関数にリンクすることで機能を実現できますprintf
。これがリンクの機能です。

3. ダイナミックライブラリとスタティックライブラリ

関数ライブラリは通常、動的ライブラリと静的ライブラリに分けられます。両者の違いは、私立と公立の違いとして理解できます。「C とポインター」という本を読む必要があるのと同じように、選択する方法は 2 つあります。1 つは、自分で本を購入し、自分だけが使用することができ、非常に便利ですが、お金がかかるという欠点があります。2 つ目は、図書館に本を借りに行く必要があり、図書館のリソースは全員で共有されることです。

gcc関数ライブラリをリンクする場合、静的リンクまたは動的リンクを選択できます。

  1. 静的リンクは、自分で本を買うのと似ています。お金がかかるだけ (メモリの無駄) です。静的リンクでは、ライブラリ ファイルのすべてのコードが実行可能ファイルに追加されるため、生成されるファイルは比較的大きくなります。
  2. 動的リンクは、図書館に本を借りに行くのと似ています。関数ライブラリは固定された場所に配置され、それを使用したいプログラムはそれ自体をロードできます。

Linuxデフォルトではgcc動的リンクが使用されます。

2 つによって生成されるファイル サイズを比較します。

//采用静态链接
gcc -static Test.c -o Test_static
//默认采用动态链接
gcc  Test.c -o Test

静的リンク中にエラーが発生した場合は、C 言語の静的ライブラリがインストールされていない可能性があるためLinux 、手動でインストールする必要があります。

//安装C语言静态库
yum install -y glibc-static

ここに画像の説明を挿入

静的リンクによって生成された実行可能ファイルは、動的リンクによって生成された実行可能ファイルよりも大きいことがわかります。

4. gcc 共通オプション

以下は、gcc コンパイラの一般的なオプションの概要です。

-E は前処理のみを有効にし、ファイルは生成しません。出力ファイルにリダイレクトする必要があります。-S
アセンブリとリンクを行わずにアセンブリ言語にコンパイルします。
-c オブジェクト コードにコンパイルします。
-o ファイルをファイルに出力します。
-static このオプションは、生成されたファイルに静的リンクを使用します。-
g はデバッグ情報を生成します。GNU デバッガはこの情報を使用できます; -sharedこのオプションは
可能な限りダイナミック ライブラリを使用するため、生成されるファイルは比較的小さいですが、システムがダイナミック ライブラリを使用する必要あります






この記事はこれで終わりです、コードテキストは簡単ではありません、たくさんサポートしてください!

おすすめ

転載: blog.csdn.net/weixin_67401157/article/details/131581525