OSについてレポート

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

OSについてレポート

投稿記事 by MoNoQLoREATOR » 12年前

このレポートは、OSが違うとプログラムが動かないのは何故なのか?また、どうすれば解決できるのか?さらに、そもそもOSとは何なのか?という謎についてのレポートになります。
以下私なりに解釈した結果だということを予めご了承ください。(つまり間違ってるかもしれないから鵜呑みにしないでねっていうこと)

まず、”OS”と言うと、次の3つのものを指すそうです。
・制御プログラム(WindowsとかMacとかLinuxとか)
・言語処理プログラム(コンパイラとか、インタプリタ型言語を実行するプログラムとか。Javaはよくわからない)
・サービスプログラム(ファイル圧縮プログラムとか)

制御プログラムは”カーネル”と呼ばれるそうです。
このレポートで述べられているOSとは、このカーネルのことを指しています。

カーネルの仕事を大雑把に説明すると、「<人間、コンピューター、周辺機器>の仲介を行う」ということになります。

○コンピューター周辺機器
周辺機器という言葉はここではマウスとかキーボートとかを意味するものとして使っています。
USBを接続したときにそれがマウスなのかキーボードなのか何なのかを識別することができるのは、おそらく周辺機器が何らかの規格に沿った電気信号を送っているからだと予想していますが検索してもHitしないからその部分は謎。

ここからは目に見えない部分についてのお話です。

まず、カーネルは記憶装置の管理を全て担当しているようです。
これは管理であってアクセスではなく、つまりどんな風に領域を割り当てるかとかを担当しているということです。
具体的には、仮想メモリの管理だとか、複数のアプリケーションを同時に走らせたりだとか、データがメモリに入りきらない場合にメモリ上の別のデータを一旦HDDに退避させたりだとかいう至難の業をやってのけているわけですね。

また、カーネルはマシンコードをプログラムメモリという特別なメモリにズラズラと配置していくという仕事を担当しているそうです。

それと、これが重要なのですが、システムコールについて調べてみました。
例えばC言語で言うfopen()は内部でopenというシステムコールを呼び出しているそうです。
ここで、マシンコードの定義を確認してみましょう。
マシンコードとは、「プロセッサが直接理解し実行できるバイナリをプログラミング言語として扱う場合の呼称」だそうです。
ちなみにプロセッサというのはCPUに内蔵されていて、「演算装置、命令や情報を格納するレジスタ」等で構成されている部品のことだそうです。
システムコールがマシンコードであるはずがないため、よってexeファイルの中身はマシンコードではないということがわかります。
また、ダイナミックライブラリはシステムコールの集まりだと言えます。
以上から、「ユーザープログラム」→「ダイナミックライブラリ」→「システムコール」→「マシンコード」といった感じで次々と変換されていくことになります。
と、いうことは…WindowsのシステムコールをLinuxのシステムコールに変換することさえできれば、WindowsのソフトをLinuxで動かすことができるということになりますよね!
…きっとそれが難しいのでしょうね^^;
WinとLinに対して「システムコール 一覧」で検索をかけてみたのですが…これは人間の手に負える仕事じゃないですね。

両者の描画アーキテクチャについて検索してみましたがそれらしいページは見つかりませんでした。(Google先生のサーチ結果をさらっと確認しただけなのでもしかしたらちゃんと記述されているのかもしれませんが)

以上です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前

Re: OSについてレポート

投稿記事 by softya(ソフト屋) » 12年前

ここで惑わすヒントです。

システムコールも機械語命令です。
あとユーザープログラムがDLLを使わずに直接システムコールすることも可能です。[訂正]

>また、カーネルはマシンコードをプログラムメモリという特別なメモリにズラズラと配置していくという仕事を担当しているそうです。

x86などパソコンで使われるCPUは命令コードもデータも同じメモリ空間に配置します。

【追記】
ついでに、exeファイルの構造
「Windows実行ファイルのバイナリ概要 (1/2):CodeZine」
http://codezine.jp/article/detail/403?p=1
「EXEファイルの内部構造(PEヘッダ) (1/3):CodeZine」
http://codezine.jp/article/detail/412
「EXEファイルの内部構造(セクション) (1/3):CodeZine」
http://codezine.jp/article/detail/413
「プログラムからEXEファイルを生成してみよう (1/3):CodeZine」
http://codezine.jp/article/detail/419
最後に編集したユーザー softya(ソフト屋) on 2012年11月01日(木) 17:03 [ 編集 3 回目 ]

ISLe
記事: 2650
登録日時: 14年前

Re: OSについてレポート

投稿記事 by ISLe » 12年前

OSとアプリケーションの区別ができていない感じですね。
というかプログラム=アプリケーションと刷り込まれてる感じですか。

DLLは実行形式の一形態で、Windowsはカーネルや各種サービスプログラムがDLLで作成されているだけです。
マシンコードの観点でEXEとDLLを区別する意味は無いと思いますよ。

OSレベルのシステムコールはハードレベル違いを吸収して統一した操作ができるように設計されているわけですが、OSごとに設計思想が違いますから、同じ機能を持ったシステムコールがあるとは限りません。
Linux(UNIX系)はクライアント・サーバーから発祥したOSで、Windowsはスタンドアロンから発祥したOSなので、根っこから違うんですよね。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: OSについてレポート

投稿記事 by MoNoQLoREATOR » 12年前

>>ソフト屋さん
そうですね。絶対にDLLを呼び出さないといけないというルールはないので、常に「ユーザープログラム」→「ダイナミックライブラリ」→「システムコール」→「マシンコード」であるというわけではないですね。

EXEファイル構造についての解説ページは既に読んだことがあるのですが、良い機会だったので読みなおしてみました。
すると、ネイティブコードに「メッセージボックスを表示する」という意味の記述がなされていることに気づきました。
ということは、どうやらシステムコールもマシンコードの一種だということになりますね。
名前から察するに、アセンブリで言うところの"call"から始まる命令がシステムコールなのだろうと思われます。
ということは、OSがプログラムをメモリにロードする際にシステムコード部分をマシンコードに書き換えているわけではなく、"call"命令によってCPUが、予めメモリに配置されている手続きを実行しに行っているということになりますね。
たしかに、そちらの方が効率が良いように思われます。

少し気になったのですが、メモリはOSが管理しているはずなのに、ネイティブコードでは参照するメモリを直接参照している?ように見えるのですが、どうなのでしょう。
もしや、特定の命令ではベースアドレス指定だと解釈されるとかいうことなのでしょうか?
最後に編集したユーザー MoNoQLoREATOR on 2012年11月01日(木) 22:15 [ 編集 1 回目 ]

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: OSについてレポート

投稿記事 by MoNoQLoREATOR » 12年前

>>ISLeさん

OSもアプリケーションも、どちらもプログラムだと私は理解しているのですかそうではないのですか?
DLLについては調べているうちにイメージが変わりました。
というのも、「EXEファイルの生成」解説ページで、「DLLの場合はこう記述する」などの記述があったため、DLLも実行ファイルの一つであるという結論に至りました。
それと、これも途中で気づいたのですが、システムコールの実際の挙動もDLLに記述されているのでしょうね。
あと、これはどうでもいいことなのですが、どの道メモリにロードされた後でしか利用することができないので先ほどの私の返信の内容
>>ということは、OSがプログラムをメモリにロードする際にシステムコード部分を
>>マシンコードに書き換えているわけではなく、"call"命令によってCPUが、
>>予めメモリに配置されている手続きを実行しに行っているということになりますね。
という記述は間違いではないと思います。

まあそんなわけで、単純に
「ユーザープログラム」→「ダイナミックライブラリ」→「システムコール」→「マシンコード」
とは表現できないということになりますね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前

Re: OSについてレポート

投稿記事 by softya(ソフト屋) » 12年前

call命令は関数の呼び出しです。
Windowsのシステムコールは、次のような仕組みで行われます。
「64ビットCPU(AMD64+EM64T)でアセンブラ」
http://www.marbacka.net/asm64/arkiv/int ... scall.html

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前

Re: OSについてレポート

投稿記事 by softya(ソフト屋) » 12年前

MoNoQLoREATOR さんが書きました: 少し気になったのですが、メモリはOSが管理しているはずなのに、ネイティブコードでは参照するメモリを直接参照している?ように見えるのですが、どうなのでしょう。
もしや、特定の命令ではベースアドレス指定だと解釈されるとかいうことなのでしょうか?
メモリ空間はハードウェアの機能(MMU)と連携してOSが管理しています。
1ページ=4096byte単位で論理アドレス空間と実アドレス空間に変換するテーブルをMMUが持っているのです。
その他、ページスワップやらメモリ保護やらの情報を持っているのもMMUです。
「メモリ管理ユニット - Wikipedia」
http://ja.wikipedia.org/wiki/%E3%83%A1% ... 3%E3%83%88
「仮想記憶 - Wikipedia」
http://ja.wikipedia.org/wiki/%E4%BB%AE% ... 8%E6%86%B6

ISLe
記事: 2650
登録日時: 14年前

Re: OSについてレポート

投稿記事 by ISLe » 12年前

先にCPUがマシンコードを実行する仕組みを勉強したほうが良いかもしれませんね。

プログラムという括りでは同じですが、実行までの手続きが異なります。
OSの話をしている部分でも、OSによるローディングを前提とした実行の話になっているような感じがします。
まあOSも巨大なアプリケーションという見方もできなくはないですが。
OSをロードする仕組みはそれ自体がひとつの大きなテーマですから興味があったら調べてみてください。

メモリ管理はメモリ管理ユニット(Memory Management Unit、MMU)を調べたら良いと思います。
あとEXE実行形式には書き換える必要のあるアドレスのテーブルを持っていてメモリにロードしたあとロードされたアドレスに応じて書き換えてから実行を開始する仕組みがあります。
DLLが公開している関数もDLLのロードアドレスとオフセットテーブルから参照されます。
Windows APIはkernel32.dllなどが公開している関数です。

システム(OSとか)があらかじめ用意しているサブルーチンをコールするからシステムコールというんです。
WindowsやLinuxでは使われませんが、BIOSコールとかDOSコールというものがあります(ました)。