実行可能ファイルがCPUではなくOSに依存するのはなぜですか?


16

Cプログラムを作成して.exeファイルにコンパイルすると、ファイル.exeにはCPUへのrawマシン命令が含まれます。(おもう)。

その場合、最新バージョンのWindowsを実行するコンピューターでコンパイルされたファイルを実行するにはどうすればよいですか?CPUの各ファミリには、異なる命令セットがあります。それでは、適切なOSを実行するコンピューターが、.exe物理CPUに関係なく、ファイル内の命令を理解できるのはなぜでしょうか。

また、一部のアプリケーションの「ダウンロード」ページのWebサイトでは、Windows、Linux、およびMac用のダウンロードがあります(各OS、86および64ビットコンピューター用に多くの場合2回ダウンロード)。CPUファミリごとにダウンロードがこれほど多くないのはなぜですか?


4
CPUには、x86、64bなどの標準があります。実行可能ファイルはCPUに依存します。あなたは特別な目的のCPUの過多が同様に存在している、あなたはRISCのようないくつかの特別なCPU上で言及したあなたのexeファイルを実行することはできません
InformedA

OSは実行可能ファイルで構成されており、OSであるため、OSではなくCPUに依存しています。
Tulainsコルドバ

下位互換性のため。
MiKL

2
多くの場合、86ビットコンピューターと64ビットコンピューターの場合、各OSに対して2つのダウンロードがあります。これは、実行可能ファイルのCPUへの依存関係として解釈します。
ムーヴィシエル

回答:


37

実行可能ファイルは、OSとCPUの両方に依存します。

  • 命令セット:実行可能ファイル内のバイナリ命令は、何らかの命令セットに従ってCPUによってデコードされます。ほとんどのコンシューマCPUは、x86(「32ビット」)および/またはAMD64(「64ビット」)命令セットをサポートしています。プログラムは、これらの命令セットのいずれかでコンパイルできますが、両方でコンパイルすることはできません。これらの命令セットには拡張機能があります。これらのサポートは、実行時に照会できます。このような拡張機能は、たとえばSIMDサポートを提供します。最適化コンパイラは、これらの拡張機能が存在する場合、それらを利用しようとしますが、通常は拡張機能なしでも機能するコードパスを提供します。

  • バイナリ形式:実行可能ファイルは特定のバイナリ形式に準拠する必要があります。これにより、オペレーティングシステムはプログラムを正しくロード、初期化、および起動できます。Windowsは主にPortable Executable形式を使用しますが、LinuxはELFを使用します。

  • システムAPI:プログラムはライブラリを使用している可能性があります。ライブラリは実行システムに存在する必要があります。プログラムがWindows APIの関数を使用する場合、Linux上で実行できません。Unixの世界では、中央のオペレーティングシステムAPIはPOSIXに標準化されています。POSIX関数のみを使用するプログラムは、Mac OS XやSolarisなどの準拠するUnixシステムで実行できます。

したがって、2つのシステムが同じシステムAPIとライブラリを提供し、同じ命令セットで実行し、同じバイナリ形式を使用すると、一方のシステム用にコンパイルされたプログラムも他方で実行されます。

ただし、より多くの互換性を実現する方法があります。

  • AMD64命令セットで実行されるシステムは、一般にx86実行可能ファイルも実行します。バイナリ形式は、実行するモードを示します。32ビットプログラムと64ビットプログラムの両方を処理するには、オペレーティングシステムによる追加の作業が必要です。

  • 一部のバイナリ形式では、異なる命令セット用にコンパイルされたプログラムの複数のバージョンをファイルに含めることができます。このような「ファットバイナリ」は、PowerPCアーキテクチャからx86に移行する際にAppleによって奨励されました。

  • 一部のプログラムはマシンコードにコンパイルされず、中間表現にコンパイルされます。これは、その場で実際の指示に翻訳されるか、解釈される可能性があります。これにより、プログラムが特定のアーキテクチャから独立します。このような戦略は、UCSD p-Systemで使用されました。

  • 1つのオペレーティングシステムで複数のバイナリ形式をサポートできます。Windowsは非常に下位互換性があり、DOS時代のフォーマットを引き続きサポートしています。Linuxでは、WineはWindows形式をロードできます。

  • 1つのオペレーティングシステムのAPIは、別のホストOS用に再実装できます。Windowsでは、CygwinとPOSIXサブシステムを使用して、(ほとんど)POSIX準拠の環境を取得できます。Linuxでは、WineはWindows APIの多くを再実装します。

  • クロスプラットフォームライブラリを使用すると、プログラムをOS APIから独立させることができます。多くのプログラミング言語には、JavaやCなど、これを達成しようとする標準ライブラリがあります。

  • エミュレータは、外国のバイナリフォーマットを解析する命令を解釈し、必要なすべてのAPIの再実装を提供することにより、別のシステムをシミュレートします。エミュレータは、最近のPCで古いNitendoゲームを実行するためによく使用されます。


10
javaと.netの両方が中間形式の使用例であることに言及する必要があります-中間形式は今日非常に人気があり、1970年代のシステムの5 1/4フロッピーから実行された遺物だけではありません。
jmoreno 14

@AKoscianskiは、提案された編集に感謝します。ただし、セキュリティ設計が実行可能ファイルがOSに依存する理由ではなく、最初にOSとユーザーランドが分かれる理由だと思います。このような保護されたオペレーティングシステムの機能に対するさまざまなAPIは、この回答の「システムAPI」セクションで既に説明されています。
アモン

2

Windowsを実行している現在のPCの99%には64ビットプロセッサがあり、32ビットソフトウェアも実行できます。他の1パーセントには32ビットプロセッサがあります。したがって、32ビットプロセッサ用に構築されたソフトウェアはどこでも実行できます。64ビットプロセッサ用に構築されたソフトウェアは、ソフトウェアの作成者が気にするすべてのPCで実行されます。

MacOS XとiOSは「ファットバイナリ」をサポートしています-実際にダウンロードしたものには、異なるプロセッサのバージョンが含まれている場合があります。PowerPCプロセッサ用のアプリケーションを作成する人はもういませんが、数年前のある時点で、実行可能ファイルにPowerPC、32ビットIntel、および64ビットIntelバージョンを含めることができ、適切なバージョンが実行されました。最近のiOSでは、アプリをダウンロードすると、デバイスのプロセッサに適したバージョンが取得されます。別のデバイスにダウンロードすると、異なるバージョンが取得されます。ユーザーにはまったく見えません。


-1

exeには、単なる生のマシンコードよりも多くの情報が含まれています。OSは、ロード時にこれを読み取り、実行方法を把握できます。

通常、コンパイル時にターゲットCPUを設定します。そうしないと、コンパイラーは現在のCPUを選択し、CPUとその古いバージョンに共通の命令のみを選択するように制限します。ターゲットCPUの特定のリビジョンに固有の派手な新しい命令を使用する場合は、コンパイラーに指示するか、組み込み関数またはインラインアセンブリコードで手動でコーディングできます。ただし、その命令をサポートしていないCPUでプログラムを実行すると、プログラムがクラッシュします。

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