web-dev-qa-db-ja.com

異なるOS用にコンパイルされたプログラム間の違い

コンパイルされたコードの観点から、あるOS用にコンパイルされたプログラムと別のOS用にコンパイルされたプログラム(LinuxとWindowsなど)の違いは何ですか。プログラムはCPU上で直接実行されませんか?それとも、プログラムがOS固有のライブラリを参照する必要があるためですか?

8
agz

通常のコンパイル済みプログラムはCPU上で「直接実行」されますが、プログラムは真空中では実行されません。

  1. 多くのプログラムは、動的にロードされる外部ライブラリ(DLLsまたは.soライブラリ)。それらをリンクする方法はコンパイラ/リンカー次第であり、各OSには異なる標準があります。ただし、すべて独自のコードを提供する「静的にリンクされた」プログラムもあります。

  2. 最新のOSは、実行中のプログラムにコンピューターの完全な制御を提供しません。プログラムは、I/O、ハードウェアへのアクセス、信号やスリープ状態への移行などの「システムコール」に依存しています。利用可能なサービスとインターフェースはOSによって定義されます。 OSは、プログラムがシステムのどの部分(メモリ、レジスタ、割り込み)を使用できるかを制御します。

  3. GUIプログラムは、画面上にそれ自体を描画するために、グラフィカルユーザー環境でも機能する必要があります。しかし、あなたはおそらくこれについてすでに考えているでしょう。

これらの理由から、OSに依存しないアプリケーションは、Javaランタイムによって提供されるような、ある種の「仮想マシン」に依存する必要があります。重要なのは、a VM = OSリソース(I/O、シグナルなど)への標準インターフェイスを提供します。もちろん、Javaまたはpythonは、処理する代わりに「バイトコード」も解釈します。 Intelの命令セットの癖がありますが、それは別の話です。

6
alexis

OSが異なれば機能も異なります。 WindowsにはI/O完了ポートがありますが、Linuxにはありません。 FreeBSDにはkqueueがありますが、Linuxにはありません。 Linuxにはfutexがありますが、Windowsにはありません。また、同じことを行うさまざまな方法があります。ファイルを開くためにどのパラメーターを渡しますか?彼らはどのような順序で進みますか?オペレーティングシステムの「ファイルを開く」機能をどの程度具体的に呼び出しますか?

5
David Schwartz

一般に、プログラムは、 アプリケーションバイナリインターフェイス(ABI) の違いにより、互換性がありません。

プログラムはCPU上で直接実行されませんか?

[〜#〜]いいえ[〜#〜]!これがオペレーティングシステムの仕事です。防止アプリケーションがCPU上で「直接」実行されるのを防ぎます。通常、最下位レベル(つまり、OS APIが構築されているレベル)では、アプリケーションはオペレーティングシステムの kernel とインターフェイスします。

コンパイルされたプログラム自体がOS固有のライブラリを参照する必要があるためですか?

はい。多くのOSライブラリは、オペレーティングシステム自体とのインターフェイスを容易にするために作成されていますが、クロスプラットフォーム用に作成されたものも同じくらい多くあります。これらは、開発者から低レベルのOSインターフェースを隠し、そのOSのコンパイル済みバージョンが実行時に利用可能になることを前提としています(以下を参照)。

ライブラリはクロスプラットフォーム方式で書き込みにすることができますが、コンパイル時にrunクロスプラットフォームにすることはできません。オペレーティングシステム(カーネル)の特定の基盤となるコンポーネントを利用するには、特定のターゲットオペレーティングシステム用に再コンパイルする必要があります。

あるOS用にコンパイルされたプログラムと別のOS用にコンパイルされたプログラムの違いは何ですか?

最後に、実行可能ファイル自体には、非常に特殊なバイナリロードヘッダーなどが含まれていることがよくあります(たとえば、Windowsの場合は PE Executable ファイル形式[.exe、.dllなど...]、または [〜#〜] elf [〜#〜] Linuxの場合[none、.o、.soなど...])。これらには、特定のソフトウェアライブラリ用にコンパイルされたOS固有のバイナリをロードするコードを含めることもできます。


最後に、プログラマーの観点から: 呼び出し規約 。コンパイルされたコードは、変数を特定の方法で(つまり、レジスタを介して、またはスタック上で)非常に特定の順序で関数に渡します。それでも、関数呼び出しを「クリーンアップ」する責任があるのは誰か(呼び出し元または呼び出し先?)についても合意する必要があります。いくつかの標準的で広く使用されている x86呼び出し規約 がありますが、特定のオペレーティングシステムではサポートされていないものもあります(これはABIの一部です)。

5
Breakthrough