2016-12-14 6 views
2

私はCで書かれたプログラムを持っていて、2台の同一のコンピュータを持っています.1台はWindows、もう1台はLinuxです。コンピュータは同一であるため、プロセッサの命令セットは同じであるため、コンパイル後のマシンコードは同じでなければなりません。では、なぜ私のプログラムを2回コンパイルする必要がありますか?私は、OSに関連する関数、または実際のOSに依存するものを呼び出さないとします。マシンコードがOSの種類によって異なるのはなぜですか?

+6

実行形式が異なります。 –

+7

OS機能などを呼び出すことは避けられません。あなたのプログラムが目に見えるような効果を持たせたいとは限りません。 –

+0

なぜ違いますか?それはプロテクトモード/カーネルモードに関係していますか? プロセッサが同一であれば、同じマシンコードを実行しないでください。 –

答えて

6

マシンコードはOSに依存せず、同じCPUで同じです。

ターゲットのCPUモード(x86 32bと言う)でOSに依存しないマシンコードを作成し、それをいくつかのROMメモリにロードして使用できるようにするならば、Windowsと(実際のメモリをマップして実行可能な権利を与えるためには全く別のOS APIによって)Linux上で動作し、そこにジャンプします.ROMのマシンコードも同じように動作します。

なぜ私のプログラムを2回コンパイルする必要がありますか?私は、OSに関連する関数、または実際のOSに依存するものを呼び出さないとします。

あなたがする必要はありません。しかし、通常はあなたのコードにいくつかのエントリーポイントが必要です、そして、普遍的なエントリーポイントを提供する方法は、OS定義のABI(Application Binary Interface)に従うことです。例えば32bウィンドウでは、スタックから引数を読み込み、64bあなたがレジスタで引数を受け取った場合(可能な場合)プロシージャのプロローグコードを正しい方法で引数を選択するように調整しないと、「他の」OSの間違った入力が書き込まれるよりも正しく動作します。

しかし、マシンコード自体、CPU命令は同じです。

しかし、x86では、過去の下位互換性のために状況が少しばかげているので、CPUは16bモード、32b [保護]モード(それらの2つ以上の異なる設定)、または64bモードになる可能性があります。 80386 CPU命令mov eax,1は、16bモードと32bモードで異なるマシンコードエンコーディングを持ちます。

同じCPUモードをターゲットにしている限り、同じ命令のマシンコードは同じ方法でコンパイルされます。異なったABIに従うためにソースを違う形で書くだけです。

実行可能ファイル...それぞれの形式が異なっていますが、これも「OSごと」ではなく、ほぼすべてのx86 OSがいくつかの実行可能ファイル形式をサポートしているため、ファイルに格納されているマシンコード(マシンコードをメモリにロードして実行するためにOSによって使用され、実行のためにセットアップされる)は全く異なります。

実用的な例は、Windows実行ファイルを実行できるWindows OSをシミュレートするための偽OSフックポイントを提供し、Windows実行可能バイナリを理解することによってメモリに正しくロードすることです。このようなWindowsアプリケーションのマシンコードは、それ以上のパッチを適用することなくネイティブに実行されます。

+1

もう1つのメモ。アセンブラは通常 "オブジェクトファイル"を生成します。これはツールチェーン固有のフォーマットになっているため、Microsoft Visual Studioでは ".o"を生成するLinux上でgccと同じアセンブラされたマシンコードを保存するために異なる ".obj"ファイルが使用されます。オブジェクトファイルのマシンコード部分は同じですが、そのようなファイルのリンクを可能にするメタデータは、(異なる形式のデバッグメタデータなど)完全に異なる場合があります。つまり、なぜ同じソースを何度もコンパイルする必要がある理由の1つですが、OS単位ではなくツール単位でのコンパイルです。 – Ped7g

+2

また、ABIのタイプのサイズの違いは「long」はx86-64 Windowsでは32ビットですが、System V x86-64 ABIでは64ビットです。したがって、同じC構造体は、異なるABIのためにコンパイルされたときに異なるものを意味する可能性があります(単一の変数は異なるサイズであるため、機械コードでは異なるオペランドサイズ、ローカルの異なるスタックレイアウトなどが必要です)。 –

+2

悪い「ツールチェーンごと」よりもこれはツールチェインごとのバージョンです。中間ファイルのバイナリ互換性は、特定のベンダーのすべてのツールで永続的に保証されません。 GCCの人々がここで後方互換性を提供しようとしているかどうかは分かりませんが、Microsoftは明示的にそうしていません。 (これはむしろ皮肉なことです)クロスツールチェーンで動作する唯一のものは、標準化されたフォーマットを持っているため、デバッグ情報です。しかし、もちろん、標準についての最も良い点は、COFF、ELF、CodeView、PDB、...-)から選択できるものがたくさんあることです。 –

関連する問題