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


8

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

回答:


6

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

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

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

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

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


さらに、OSごとにスタックレイアウトやメモリアライメントの慣行などの基準が異なるため、純粋に数値/計算コードであっても、OSごとに異なる必要がある場合があります。
ダニエルRヒックス2013年

これらの違いにより、静的にコンパイルされたコードの実行が妨げられますか?知らなかった..
アレクシス2013年

他の非互換性が最初にあなたを得るので、それはおそらく単なる理論上の問題です。ただし、OSは、スタックフレームの配置方法、レジスタの格納場所などを期待します。これらは、同じハードウェアアーキテクチャでもOSによって異なる場合があります。理論的には、純粋に計算的な「外部」コードを実行できるかもしれませんが、それを開始したり、クリーンに終了したりすることはできません。
ダニエルRヒックス2013年

5

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


それは理にかなっていますが、一般的には、プログラムをメモリにロードしてCPUで実行するか、OSがプログラムを「制御」します
agz

1
@agovizer:両方。それらは相互に排他的ではありません。通常、OSは制御された環境を設定し、ハードウェアが特定の時間内にプログラムを中断し、コアをプログラムに引き渡すように調整します。ただし、プログラムが任意の数の条件(ページフォールト、I / O操作など)に達するとすぐに、OSが再び引き継ぎます。
David Schwartz

5

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

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

いや!これがオペレーティングシステムの役割であり、アプリケーションがCPUで「直接」実行されないようにします。通常、最低レベル(つまり、OS APIが構築されているレベル)では、アプリケーションはオペレーティングシステムのカーネルとインターフェイスします

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

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

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

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

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


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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.