SPO 666週5反射
4689 ワード
こんにちは皆さん、SPO 600(ソフトウェア可搬性と最適化)反射と余分の探査ブログの週6にようこそ!我々は5週間のアセンブリ言語を学んでいる.今週、私たちはCプログラムがどのように構築され、コンパイルされ、最適化されるかについて話します.
Cプログラマの初心者として、ソースコードがバイナリ実行ファイルになる方法に興味がありますか?今日から始めます.
このソースコードをコンパイルしたいなら、Linuxシステムに必要なのは以下の通りです.
The gcc コンパイラは5つのステップを実行します.プリプロセッサ、コンパイル、最適化、アセンブリ、リンク.
具体的には別の例を挙げたいと思います.
前処理
前処理はヘッダーファイルの宣言をその内容に置き換えます.処理の後、あなたはより大きなファイルを得ます.テストを前処理するには、以下のコマンドを使用できます.c
- Iヘッダファイルのフォルダを決定する.
- Oは出力ファイルの名前を決定することです.
とテストのサイズ.私はテストのために17691 Bです.Cは146 Bである.
編集
この部分のコンパイルは、プリコードされたコードをアセンブリコードに組み立てることです.次のコードを使用できます.
アセンブルする
アセンブルはアセンブリコードをmachine code . この手順では、バイナリ形式のオブジェクトファイルを作成します.使えます
リンク
リンクプロセスは、プログラムが最終的に作成する必要があるすべてのライブラリファイルを接続しますexecutable file(.exe) .
結論と私の想い
上記の手順によると、私たちは、プロセスが前に考えたものではないことがわかりました.コンパイルは私たちがアクセスするための実行可能ファイルを作成するために5つの手順を経て、ソースコードファイルを正常にコンパイルするには、上記のパイプラインから任意の1つのステップをスキップすることはできません.
しかし、まだ使用することができますので、あまり心配しないでください.
Cプログラマの初心者として、ソースコードがバイナリ実行ファイルになる方法に興味がありますか?今日から始めます.
// hello.c
#include <stdio.h>
int main(){
printf("hello world!\n");
}
我々は、すべてのプログラマのための最初のプログラムです簡単なHelloWorldプログラムから起動します.このソースコードをコンパイルしたいなら、Linuxシステムに必要なのは以下の通りです.
$ gcc hello.c # compile
$ ./a.out # execute
hello world!
私たちがコードを実行するのは非常に一般的です、しかし、我々が上記で見るものと同じくらい単純なこのプロセスですか?答えは何ですかgcc 上記のコンパイル期間中は実際に行います.The gcc コンパイラは5つのステップを実行します.プリプロセッサ、コンパイル、最適化、アセンブリ、リンク.
具体的には別の例を挙げたいと思います.
// mymath.h
#ifndef MYMATH_H
#define MYMATH_H
int add(int a, int b)
int sum(int a, int b);
#endif
// mymath.c
int add(int a, int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
// test.c
#include <stdio.h>
int main(){
int a = 2;
int b = 3;
int sum = add(a, b);
printf("a=%d, b=%d, a+b=%d\n", a, b, sum);
}
このプログラムでは、我々は単に2つの整数の合計を見つけるために作成しました.前処理
前処理はヘッダーファイルの宣言をその内容に置き換えます.処理の後、あなたはより大きなファイルを得ます.テストを前処理するには、以下のコマンドを使用できます.c
gcc -E -I./inc test.c -o test.i
または$ cpp test.c -I./inc -o test.i
- eコマンドで前処理が終了したら終了する.- Iヘッダファイルのフォルダを決定する.
- Oは出力ファイルの名前を決定することです.
とテストのサイズ.私はテストのために17691 Bです.Cは146 Bである.
編集
この部分のコンパイルは、プリコードされたコードをアセンブリコードに組み立てることです.次のコードを使用できます.
$ gcc -S -I./inc test.c -o test.s
テストの内容.sは以下です .file "test.c"
.section .rodata
.LC0:
.string "a=%d, b=%d, a+b=%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $2, 20(%esp)
movl $3, 24(%esp)
movl 24(%esp), %eax
movl %eax, 4(%esp)
movl 20(%esp), %eax
movl %eax, (%esp)
call add
movl %eax, 28(%esp)
movl 28(%esp), %eax
movl %eax, 12(%esp)
movl 24(%esp), %eax
movl %eax, 8(%esp)
movl 20(%esp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
私が知っている限りではassembly code 本当にここに.私がそれを理解するならば、私はこれのためにもう一つのポストをつくります.アセンブルする
アセンブルはアセンブリコードをmachine code . この手順では、バイナリ形式のオブジェクトファイルを作成します.使えます
gcc -c test.s -o test.o
すべてのソースファイルのオブジェクトファイルを作成します.リンク
リンクプロセスは、プログラムが最終的に作成する必要があるすべてのライブラリファイルを接続しますexecutable file(.exe) .
結論と私の想い
上記の手順によると、私たちは、プロセスが前に考えたものではないことがわかりました.コンパイルは私たちがアクセスするための実行可能ファイルを作成するために5つの手順を経て、ソースコードファイルを正常にコンパイルするには、上記のパイプラインから任意の1つのステップをスキップすることはできません.
しかし、まだ使用することができますので、あまり心配しないでください.
$ gcc hello.c # compile
$ ./a.out # execute
Reference
この問題について(SPO 666週5反射), 我々は、より多くの情報をここで見つけました https://dev.to/qzhang125/spo-666-week-5-reflection-34a5テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol