コンピュータ・プログラムでは、それがどのように動作するかです
大学4年間が、この問題のコンピュータ科学の深い理解していない。
唯一の漠然としたアイデアプログラムは、コンピュータ上のバイナリ実行ファイルにコンパイルする必要があります実行することができます。
?最近、突然、特に同じような種類どのように具体的に知っている
。だから、レコードに関する記事を書くことについて考えて
この質問、私はそれは確かに深いビューを持つことになり、数年以上待ちたい。
、理解ない場所があってくださいしない場合補正。
プログラムは、コンピュータ上で実行され、
アプリケーションが実行されると、コール処理オペレーティングシステムなしで行うことはできません。
アプリケーションはプログラミング言語で書かれています。
最初に書かれた:2020年2月23日
コンピュータ
現代社会は、すでに生産手段、自明の重要性など、コンピュータなしで行うことはできません。
コンピュータの歴史
ショートコンピュータの歴史が、開発は非常に急速であり、
大型機械から、今の携帯電話にフラットのフロア全体を占めている。
機能がより強力になって、さらに広く使用となっています。
しかし、この事は?パソコンを持っていない理由を考える
私たちは、コンピュータが存在しない状態で生きてあまりにも良いではないですか?
開発し、人々が唯一のマンパワーや簡単なツール(例:そろばん)を算出する処理に依存することができます前に、コンピュータのハンドルに、
人々のニーズを満たすことができません。
だから我々は、前任者の努力でコンピュータが開発しました。
。それは開始点として、現実の問題に基づいており、技術の多くを学ぶ
、私たちはこの技術と技術の歴史を必要とする理由を理解理解し、使用することは非常に重要です。
コンピュータの構成
フォンノイマンコンピュータシステムは、次の5つの部分と対応する実際のハードウェアを持っています。
- 電卓CPU
- コントローラのCPU
- RAMメモリ、ハードディスク
- などの入力デバイスキーボード、マウス、
- 出力ディスプレイ等の機器部品
CPUは、レジスタや算術を含み
。私たちは、それが唯一のバイナリデータを扱うことができるコンピュータを知りたい
ほとんどの人がやっていることは計算コンピュータに移動するバイナリの道を開始しています。
ピープル紙パンチ、0/1を表現し、コンピュータに計算するのに使用される;.される
しかし、これはあまりにも人間、それが面倒です。
人々は、アセンブリ言語を発明し、
アセンブリ言語、読んで理解できる人間とみなすことができる。
一般的に、これは以下のとおりであります:
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $2, %esi
movl $1, %edi
call sum
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
いくつかのこのようなコードがあったものの読み取り可能であるだけでなく、より書き込みに嫌。
そして、それぞれのCPUの機械語命令が同じではない、対応するアセンブリ言語は同じではありません。
このように、人々はより便利ハンドラ;.クロスプラットフォームや言語することができ、本発明を考える
このように、C言語が出て発明されました。
多くのシステム、プログラミング言語の基礎となるC言語の非常に重要な外観。
Cは言語を反映するように見える二つの重要なアイデアを、人々バイナリパッケージアセンブリ言語命令に、機械は人を分離します。封装
分层
さらに、再度コンパイルパッケージ、クロスプラットフォームのプログラムは、異なるハードウェア上で実行することができ、
ユーザに対して透過基本となる実装の詳細をシールド;
Cは普遍的な言語、手続き型言語のためのコンピュータプログラムです。1972年には、UNIXオペレーティングシステムの移植・開発するためには、ベル研究所のデニス・リッチーは、C言語のデザインを開発しました。
オペレーティングシステム
コンピュータのオペレーティングシステムを使用すると、プロセスの産物です。
最初は、何のコンピュータのオペレーティングシステムではありません。
コンピュータの後、弱い容量、コンピューター利用することができます。
しかし、コンピュータのハードウェアの継続的な発展と、巨大なアップグレードを得るために、コンピュータの能力。
これは、コンピューティングリソースの無駄の多くを作成します。
なぜべきオペレーティングシステム
何時間オペレーティングシステムが存在しない場合は、人間機械の生産性と効率性は比較的低いです。
オペレーティング・システムは、簡単な操作コマンドをユーザーに提供するために、と手順を試運転、システムソフトウェア設計言語処理プログラムを容易にするようにします。
コンピュータリソースの利用率を向上するだけでなく、実装の詳細の一部を遮蔽し、
オペレーティングシステムや他のソフトウェアとのベアメタルシステムの後に、それはコマンドだけで理解するだけでなく、コンピュータシステムを使用して動作するように簡単に、様々な高レベルの言語を理解するになります。
問題を解決するために、オペレーティングシステム
コンピュータのオペレーティングシステムは、大規模システムのプログラムを搭載した、独自のコンピュータシステムのハードウェアとソフトウェアのリソース管理を実現するためにそれを使用しています。
- コンピュータのリソース使用率を増やし、
- コンピュータシステムの性能を向上させるために、コンピュータシステムの応答速度の向上
- ユーザーフレンドリー
Linuxオペレーティングシステム
通常の状況下で、我々は、実行するプログラムを開発してきたLinux操作系统
上に、
それゆえ、以下の例は、Linuxをベースにしています。
Linuxシステムが構成されてC语言
と汇编语言
書かれ、
続くPOSIX
システムインターフェースを、プログラムの移植性を保証します。
POSIXポータブルオペレーティングシステムインタフェース(POSIX略記UNIXのポータブルオペレーティングシステムインタフェース)、POSIX標準定義は、オペレーティングシステムへの標準インタフェースは、アプリケーションによって提供されなければならない表します。
C言語
C言語では、書き込みのUnixの時間の積です。
なぜべきであるC言語
コンピュータソフトウェアの開発プロセスは、プロセスの効率を高めるための継続的な最適化です。
UNICSの発明は、複雑なタスクの処理を簡素化することです。
一方、新しい言語(C)を簡略化し、再作成するために、関連するハードウェアおよびソフトウェアに対処するためには、
最新のオペレーティング・システム(UNIX)の開発のためのソフトウェアとハードウェアの分離を達成するために強固な基盤を築きました。
この問題を解決するためのC言語
解決するために、C言語
- 移植性の問題手続き等のAプログラムは、マシンの異なる種類の上で実行することができます。
- より良いコードの可読性と
言語のブートストラップ
コンパイラによって、C言語で書かれたプログラムは、実行可能ファイルにコンパイルすることができます。
C言語コンパイラ
単純なものから、次の手順に
- 前処理:ヘッダを展開/マクロ置換/アンコメント/条件コンパイルされたファイル.I [プリプロセッサCPP]
- コンパイラ:[されるコンパイラEGCS]、プレアセンブリ言語にファイルを変換するファイルを生成する.S
- アセンブリ:コンパイルは、ターゲット・コード(機械コード)生成の.oファイル[アセンブラなど]となります
- リンク:Connectionオブジェクトコード、実行可能プログラム生成[リンカLD]
前処理
これは非常にシンプルなC言語のコードのファイル名hello.cであります
#include <stdio.h>
int sum(int a, int b)
{
return a + b;
}
int main(int argc, char const *argv[])
{
int a = 5;
int b = 8;
int c = sum(a, b);
printf("%d \n",c);
return 0;
}
出力がファイルにリダイレクトされている間私たちは、この文書が生成されていない、事前にアクティベーションを実行できます
gcc -E hello.c > hello.i
この時点で、我々は得ることができます
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
// 这里省去了很多引入的代码
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 944 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
# 3 "hello.c"
int sum(int a, int b)
{
return a + b;
}
int main(int argc, char const *argv[])
{
int a = 5;
int b = 8;
int c = sum(a, b);
printf("%d \n",c);
return 0;
}
コンパイル
前処理した後、さらに変換するための必要性汇编代码
gcc -S hello.c
いくつかのコードを除去した後
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $5, -4(%rbp)
movl $8, -8(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %edx, %esi
movl %eax, %edi
call sum
movl %eax, -12(%rbp)
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
.section .note.GNU-stack,"",@progbits
編集
前処理、コンパイルを活性化し、組立、つまり、彼は唯一のプログラムOBJファイル作っだけ
プロセスが呼び出された後、文書の編集を目标文件
gcc -c hello.c
バイナリファイルhello.oを生成します
が、プログラムを実行することができませんでした。この時は、まだリンクする必要があります。
リンク
なぜそれがマシンで実行される前に、後にコードをリンクする必要がありますか?
コンパイラは、単にバイナリ形式に私たち自身のコードを記述しますので、
それが必要と(例えば、標準ライブラリ、ダイナミックリンクライブラリなど)のシステム・コンポーネントは、一緒に、
これらのコンポーネントは、プログラムを実行するために必要です。
C標準ライブラリ、コンパイラ、またはオペレーティングシステムにありますか?
で操作系统
異なるオペレーティングシステムは、異なるライブラリを提供します
- Linuxのgccを接続するために使用されます
libstdc++.so
- マック利用打ち鳴らすを接続する場合
libc++.so
そのようなオペレーティングシステムは、ライブラリとして、開発者が知られている成熟した機能モジュールの数を提供し、特定のモジュールの組み合わせ;
に組み込まれ、これらのコネクタモジュールを使用して、開発者がプログラムとなり、彼らリンクライブラリと呼ばれます。
異なるオペレーティングシステムでインストール・パッケージが同じでない理由、これは説明します。
リンク(リンク)は、実際にある打包
、プロセス
、それは単一の実行可能ファイルにバイナリファイルとシステムコンポーネントのすべてのフォームを対象とします。
プロセスをリンクすることでも、リンカーと呼ばれる特別なソフトウェアを必要とします。
我々はより多くの書き込みコードの私達の深い研究では、彼らは最終的には複数のソースファイルに分散する必要があります、
コンパイラは、唯一のソースファイル、オブジェクトファイル、コンパイルすることができ
、リンカーに加えて、この時間は、組み合わせでオブジェクトファイルとシステムコンポーネントは、コンパイラが生成したオブジェクトファイルを複数組み合わせる必要があります。
ソースファイル、あなたはどのように多くのターゲットファイルが生成される回数、コンパイルする必要があり、ソースファイルの数のためにコンパイルされています
リンクは、最終的なデスティネーションファイルの生成を参照します可执行文件
例:hello.o
ファイルや他のライブラリ・ファイル、その他のファイルは、最終的な生成されたファイルに追加されましたhello.out
で。
# -o 参数表示输出的文件名
gcc -o hello.out hello.c
リンクのモードに応じて、リンク処理を分けることができます。
- 静的リンク
- ダイナミックリンク
静的リンクライブラリ
.a
そして、.lib
それは、オブジェクトファイルの束の集合体として見ることができます。
これらの機能のいずれかが呼び出されると、接続プロセスに追加し、オブジェクトファイルそのうちにそれを置きます。
これは、ユーザーのライブラリコードとの直接接触を避けるためにも、コンパイルに時間がかかり、多くのを保存することができます。
ダイナミックリンクライブラリ
ダイナミックリンクライブラリ(.soのと.dll)が異なっています。
ダイナミックリンクライブラリを読んだ後コネクタが、それもしますが、メモリアドレス空間をコピーし、実行可能ファイルに適切なコンテンツを割り当てません。
プログラム実行オペレーティングシステムの間、DLLは、実行時に接続し、直接メモリにロードされます。
ダイナミックリンクに加えて、ライブラリ機能は、静的リンクライブラリを持つことができ、他の強みがあります。
同じダイナミックリンクライブラリを使用して、複数のプロセス場合は、
ライブラリは一度だけロードされ、その後、彼らはスペースを節約し、時間の節約だけではなく、これらのプロセスで共有することができます。
しかし、固定アドレスすることなく、ダイナミックリンクライブラリの効率は、いくつかの損失であってもよいです。
プログラムとオペレーティングシステム
C言語では、我々は語ら链接
の必要性である操作系统
。提供するライブラリ関数
プログラムの実行もに依存している操作系统
リソース割り当て応答。
したがって、プログラムを実行するオペレーティングシステムを分離することができません。
プログラムは、オペレーティング・システム上で実行される方法
まず、我々はプログラムが置かれている知っている硬盘
中で、
あなたがそれを実行しない、それが死んでいます。
あなたはそれを実行したときにのみ、プログラムは、オペレーティング・システムにロードされて内存
行くように、
このプログラムは実行の開始とみなされます。
実行する場合、オペレーティングシステムはそれを操作することによって生成されたプログラムやデータを記憶するために割り当てられたメモリのセクションを与えます。
このメモリは、0x1000番地からから0x8000のように、スタートアドレスとエンドアドレスを有し、開始アドレス、終了アドレスは、そのアドレスより大きなアドレスの小さい方です。
そして、プログラムメモリ
ヒープ
プログラムの実行、動的メモリフットプリント要求中に、(例えば、新しいオブジェクト、または使用のmallocコマンドとして)
、脇ユーザの部分を設定するために予め割り当てられたメモリその期間の中からシステム意志、
特にルールの開始アドレスから部門(実際には、ここでは無視静的データの先頭アドレス、あるでしょう)。
たとえば、ユーザーが必要とするメモリの10バイトを取得し、その後、彼に割り当てられた開始アドレス0x1000番地から、
その後、0x1020に割り当てられた22のバイトを与えるために必要な、その後あれば、アドレス0x100Aに割り当てられています。
ユーザーが積極的に分割されたメモリ領域のうち要求したので、これは、ヒープ(ヒープ)と呼ばれます。
それはローから上位(アドレス)の増加(アドレス)に開始アドレスから開始します。
ヒープが自動的に消えていない重要な機能は、手動で解放する必要がありますまたはガベージコレクションメカニズムによって回収することができます。
スタック
ヒープに加えて、他のメモリフットプリントは、スタック(積み重ね)と呼ばれています。簡単に言えば、スタック機能は一時メモリエリアを占有し実行することによるものです。
関数の実行中に、
我々は確かに、一時的な変数を格納するために使用します。
スタック上のこれらの一時変数に。
説明する例
#include <stdio.h>
int sum(int a, int b)
{
return a + b;
}
void printSum(a, b)
{
int num = sum(a,b);
printf("%d \n",num);
}
int main(int argc, char const *argv[])
{
int a = 5;
int b = 8;
printSum(a, b);
return 0;
}
コールスタック
main函数
スタート、するprintSum(a,b)
機能、コールスタックにこの機能に遭遇し、
彼らは出会ったsum(a,b)
機能を、それは、関数のコールスタックに置かれます。
ない既知の関数の後、スタックに続いて、戻り値を、開始、
コンテンツは、コンテキストレコード機能を備えることを特徴とする請求あります栈帧
手続きやプロセス
プログラムが実行されている場合は、オペレーティングシステムがプログラムを管理するためのプロセスを開きます。
プロセスは、データセット上の個々の機能を有するプログラムの実行イベントです。
これは、動的な概念であり、それはアクティブなエンティティであり、システムやリソースを持つように適用することができます。
それだけでなく、さらなる処理のレジスタの内容によって表される現在のアクティビティを含むプログラムコード及び該プログラムカウンタの値であります
スレッド・プログラム
当社のソフトウェアは、ハードウェア要件はますます高くなっている場合は、同時に実行されるコンピュータプログラムは、より多くのであり、
かつCPU、切り替えの処理中に、それは資源の無駄の多くになります。
- プロセスがリソースの所有者、作成され、撤回するスイッチングの大きな時空のオーバーヘッドがあり、軽量プロセスを導入する必要があります。
- なぜなら対称マルチプロセッサ(SMP)の並列オーバーヘッドで複数のプロセスが大きすぎるしながら、複数の演算ユニットを満たしています。
したがって、この問題を解決するために:线程
がありました
スレッド(英語:スレッド)が操作スケジューリングが可能なオペレーティングシステムの最小単位です。
これは、プロセスの単位プロセスの実際の動作が含まれます。
スレッドは、スレッドが親プロセスを持っている必要があり、プロセスが複数のスレッドを持つことができ、プロセスの実体です。
线程
システムは、データ構造の一部だけを実行する必要があり、リソースを持っていない。
それは親のある其它线程
プロセスが所有シェア全部资源
。
あなたはスレッドを作成し、プログラムの同時実行を実現するために、スレッドを元に戻すことができます。
スレッドがあり
- レディ
- おもり
- ラン
参考記事