実行可能なバイナリファイルが実際にどのように動作するのか、私はいつも疑問に思っていました。コンパイルは常に次のように説明されています。
ソースコードを取得して機械語に翻訳する
しかし、それは実際には何を意味するのでしょうか? つまり、
- バイナリ ファイルをコンピューター A からコンピューター B に移動して、正常に動作することは期待できますか? (適切なライブラリも移動することを前提とします)
- すべての実行可能バイナリ ファイルは特定のプロセッサで動作するように作成されていますか?
- 実行可能バイナリ ファイルにはどのような情報が含まれていますか?
- Windows 上の実行可能ファイルは、どのバージョンの Windows でも起動できるのはなぜですか? (動作するかどうかは別の話です)
- Windows で Linux 実行ファイルを実行できないのはなぜですか? カーネル (プロセッサではない) に関係があるのでしょうか?
ただし、プロセッサとコンパイラに関する私の知識は限られており、アセンブリに関する知識はまったくありません。
答え1
- 必ずしもそうではありません。移植性を考慮して構築されており、プラットフォームに互換性がある場合は、可能です (たとえば、64 ビット版の Windows では、32 ビットおよび 64 ビットの Windows 実行ファイルを実行できますが、16 ビットのものは実行できません)。
- 必ずしもそうではありません。特定の命令セット用に作られています。これらは通常拡張機能であり、下位互換性があるため、古いファイルを新しいプロセッサで実行できるかもしれませんが、その逆は必ずしもそうではありません。たとえば、Windows 95 用にコンパイルされたプログラムは、おそらく今日のハードウェアでも実行できますが、今日のハードウェア用にコンパイルされたプログラムを古い Windows 95 マシンで実行することはできません。ただし、2 つのマシンがまったく異なる命令を実行する場合、実行ファイルは互換性がありません (例: Intel と ARM)。
- これはプラットフォームに依存しており、異なるヘッダーなどを持つ複数の形式がありますが、基本的にはインデックスとして機能する何らかのヘッダーが常に存在し、オペレーティング システムに特定のもの (メイン エントリ ポイントなど) がどこにあるかを伝えます。
- 実際にはできません (上記の 2 を参照)。
- まず、Windows と Linux は実行ファイルの形式が異なります。しかし、それでも、たとえば環境全体や提供されるプラットフォーム API/ライブラリなど、違いはあります。たとえば、Linux 実行ファイルは通常、X11 などのウィンドウ マネージャーと通信しようとしますが、Windows プログラムは Windows API を呼び出そうとします。ただし、このようなことを機能させる方法はあります。Windows の古いバージョン (NT?) には実際に POSIX 拡張機能があり、私が知る限りでは限られた Linux プログラムを実行できましたが、実際に試したことも詳しく調べたこともありません。一方、Linux には Wine などのツールがあり、API ファイルやパス変換などを提供して Windows 環境をエミュレートしようとします。完全なエミュレーション (仮想マシンを使用する場合など) ではありません。
答え2
厳密に管理された状況でのみ: 両方のコンピューターに互換性のあるプロセッサとオペレーティング システムが搭載されている必要があります。
特定のプロセッサではなく、互換性のあるプロセッサのセットです。たとえば、x86 との互換性のためにコンパイルされ、拡張子のないファイルは、OS に互換性があると仮定すると、すべての Intel または AMD x86 または x64 プロセッサで動作します。
まず第一に、コンパイル ステップからのマシン コードです。それに加えて、いくつかのいわゆる「セクション」には、たとえばリソース (実行可能ファイルが実行中でなくても、エクスプローラーに表示される Windows 上の専用アイコンがあるのはなぜか、不思議に思ったことはありませんか)、バイナリ互換性の説明などがあります。
これは 1. の副作用です。OS が実行可能形式との互換性を提供する場合はいつでも起動できます。最新の Windows バージョンはさまざまな互換性を提供します。最も重要なのは DOS、Win16、Win32、Win64、dotnet です。
OS は実行可能ファイルに実行に不可欠な環境を提供します。Linux と Windows では環境が大きく異なります。つまり、一方の実行可能ファイルをもう一方の OS で直接実行することはできません。このギャップを埋めるために、現在プロジェクトが進行中です。WINE プロジェクトは、Windows 実行可能ファイルを Linux (および他の OS) で起動できるようにすることを目標としており、Cygwin プロジェクトは、Linux ソフトウェアを Windows で実行できるようにすることを目標としています。Cygwin はバイナリ互換性を目標としているのではなく、変更されていないソースの再コンパイルを可能にすることを目標としています。
実行ファイル(例:.exe)は、ないコンパイルプロセスの結果 - それはリンクプロセスは、コンパイルの出力と、3 で説明したものを作成するために必要な他の要素を組み合わせます。