質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

7回答

18244閲覧

カーネルがC言語で書かれているということが納得できません

sachito

総合スコア13

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

8クリップ

投稿2018/03/28 09:17

編集2018/03/28 09:21

根本的な理解が足りていないのかもしれませんが、質問させてください。

C言語でHelloWorldプログラムを作ったとします。
その中で、以下のコードがあります。

printf("Hello World");

この部分を実行すると、標準Cライブラリがwrite()システムコールを発行して
カーネルに実行が移り、ディスプレイに「Hello World」が表示されます。

この説明は理解できますが、そのカーネルの処理がC言語で書かれているというのが理解できません。

write()システムコールに対応するカーネル処理のソースコードはC言語で

printf("~");

と書かれているのでしょうか?
メモリを直接操作するようなコードをアセンブリで書くのではないでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

ベストアンサー

まず、Cにはホスト環境とフリースタンディング環境という二つの環境があることをご存じですか?

よく見る通常のCのプログラム、printf関数などを使ったプログラムはホスト環境と言われるもので、OS上で動作すること前提としています。各標準Cライブラリの各関数の動作はOSが環境を用意しているからこそ、動作できると言うことです。

対して、フリーホスティング環境はOSを前提としないプログラムです。OSが提供するような機能が使えないため、標準Cライブラリも限られた物しか使えません。printf関数はもちろん、プログラムを終了するためのexit関数すら使えないようになっています。その代わり、main関数がエントリーリポイントになるという制約から外れ、その環境に応じたエントリーポイントから始まることになります。

カーネルはOSの役目を担うのですので、もちろん、OS上で動作する物ではありません。ということで、カーネルはCでできていると言っても、通常見るようなホスト環境ではなく、フリースタンディング環境のCで書かれています。つまり、カーネルが書かれているフリーホスティング環境には、そもそもprintf関数が存在しないのであり、writeを実装しようにも、他の方法を使わなければなりません。アセンブリでシステムコール呼び出しを実装し、それらのシステムコールを駆使する形で作られることになります。

そもそも、カーネルはCだけでできているのではありません。1.5%はアセンブリでできています。しかし、アセンブリで全て書くことは全く現実的ではないため、Cでは直接記述できないCPUへの特権命令等をアセンブリで書いて、それらをシステムコール等としてまとめて、Cであればどこからでも使える関数(またはマクロ関数)にしています。そして、ただの計算処理だけを行うような部分、つまりは、別途作成したシステムコール等があれば実現できるような部分をCで書いていると言うことです。そして、そういった部分が大部分を占めるため、ほとんどがCでできているように見えると言うだけです。

参考:

投稿2018/03/28 11:34

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sachito

2018/03/29 02:39

ホスト環境とフリースタンディング環境というのを知りませんでした。 とても分かりやすい説明ありがとうございました。
guest

0

Linuxだったらカーネルのソースコードを実際に読んでみてはいかがでしょうか。

ネットで検索すれば、親切な方がわざわざどのあたりがどのファイルかなど解説してくれているサイトなどもあります。

例)The Linux Kernel

そこで納得いかなければ再度質問されてはいかがでしょうか。

投稿2018/03/28 11:39

KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sachito

2018/03/29 02:41

ありがとうございます。見てみます。
guest

0

「カーネルがC言語で書かれている」といっても、当然ながら標準ライブラリは使えません(逆に、標準ライブラリがカーネルを使って実装されています)。実際の出力部分は、アセンブラあるいはCのメモリ操作で書かれていることと思います。

カーネルの大半がC言語で書かれている理由としては移植性があります。CPUやハードウェアに依存する一部のコードだけアセンブラで書くようにして、残りのコードはコンパイルさえすれば環境を超えて使えるようになっています。

投稿2018/03/28 09:39

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sachito

2018/03/28 09:56

ご回答ありがとうございます。 >アセンブラあるいはCのメモリ操作で書かれていることと思います。 こちらのCのメモリ操作は、ライブラリ関数を使わずにポインタを使っているという認識であっていますでしょうか?
sachito

2018/03/28 10:08

立て続けに失礼します。 >当然ながら標準ライブラリは使えません(逆に、標準ライブラリがカーネルを使って実装されています) とありますが、標準ライブラリが内部で結果的にシステムコールを発行し、カーネルに処理を依頼しているから。と捕らえて大丈夫でしょうか?
Zuishin

2018/03/28 10:13

カーネルではなくディスプレイドライバの仕事ではありませんか?
a_saitoh

2018/03/31 00:20

標準ライブラリのすべてがカーネルでは使えないわけではなく、strcmpみたいなシステムコールを内部では呼び出さないものは、使えます。
guest

0

write()システムコールに対応するカーネル処理のソースコードはC言語で

Linux/Unix だと多分、そうでしょう。
他のOSではどうかは知りませんが、昔、使った事のあるOSでは違いました。(C言語は後から、サポートされていた) C言語である必要は無いが、C言語が主流になっただけです。

実際のコードについては、

printf("~");

という事はありえません。別の方が書かれているように、カーネル、、、と言うより、標準ライブラリのソースを読めば、分かると思いますが、printf()は、内部的に、write()を呼び出しているのでは思います。(最近の見てないので本当のところは知りませんが) また、大昔の様に直接、端末に出力するような時代ならともかく、今時は、出力用のデバイスドライバ呼出ししかないと思いますので、標準化された(デバイスドライバ)呼出しを行っていると思います。
あと、カーネルでの処理ですが、時代によってカーネルの範囲(定義)は異なりますが、今はどの辺でしょうか? Linux/Unix は比較的狭い範囲と理解していますが、標準ライブラリと 外部I/Oのやり取りくらいは含むかな、、と思います。

余談ですが、C言語は昔、高級アセンブラと呼ばれていました。その位、アセンブラに近いという事で、アセンブラに近い効率を簡潔な表記で記述できます。

投稿2018/03/28 12:07

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sachito

2018/03/29 02:42

ご回答ありがとうございます。勉強になりました。
guest

0

おおよそ認識はあっているかと思います。
ユーザー空間でprintfを呼び出すと標準ライブラリでstdout(ファイルディスクリプタ1)に対してwriteシステムコールを発行します。ファイルディスクリプタを使って対応するデバイスドライバが選ばれ呼び出されます。writeシステムコールの中身はデバイスドライバに実装されています。

デバイスドライバがどのように実装されるかはハードウェアによって異なるので一概には言えません。またデバイスドライバは何層にも重なっているので一番始めは抽象化されたttyデバイスになりますが、最終的にはメモリ操作かIO操作になります。(C言語的にポインタを使うか、IOのための専用命令を出すためにアセンブラで記述する)

投稿2018/03/28 22:13

nullbot

総合スコア910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sachito

2018/03/29 02:42

ご回答ありがとうございます。勉強になりました。
guest

0

こんにちは。

C言語は大きく2つの部分に分かれています。C言語コア部と標準ライブラリ部です。
標準ライブラリはあくまでもライブラリの一種です。例えばOpenCVなどもライブラリの一種ですね。
OSのカーネルを書く際にOpenCVを使う人はまずいないと思います。同様に標準ライブラリも使われない(使えない)関数がほとんどです。そして、printf()は標準ライブラリに含まれている関数です。

C言語コア部はCコンパイラが解釈するプログラミング言語の文法を規定します。
アセンブラはアセンブリ言語で書かれたソース・プログラムをマシン語へ変換します。
CコンパイラはC言語で書かれたソース・プログラムをマシン語へ変換します。
従って、このコンパイラとしての機能を使ってカーネルを書くことになんら問題はありません。

投稿2018/03/28 12:37

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sachito

2018/03/29 02:42

ご回答ありがとうございます。勉強になりました。
guest

0

ディスプレイに文字が表示される、と言ってるうちはカーネルを云々するにはあまりに理解も知識も足りていない、と言わざるを得ません

ハードウエアがどう動いているか、どう動かさなければならないかというレベルで考えないと話になりません

投稿2018/03/28 10:59

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問