2

基本的に、私が疑問に思うのは、なぜx86-64OSがx86マシン用にコンパイルされたコードを実行できるのかということです。最初のx64システムが導入されたとき、これはそれらのいずれの機能でもなかったことを私は知っています。その後、彼らはどういうわけかこれを行うことができました。

x86アセンブリ言語はx86-64アセンブリ言語のサブセットであり、ISAは下位互換性をサポートできるように設計されていることに注意してください。しかし、ここで私を混乱させるのは、スタック呼び出し規約です。これらの規則は、アーキテクチャによって大きく異なります。たとえば、x86では、フレームポインタをバックアップするために、スタック(RAM)を指す場所でプッシュを実行し、完了後にポップします。一方、x86-64では、すべての参照がスタックポインターを介して提供されるため、プロセスはフレームポインターをまったく更新する必要がありません。次に、x86アーキテクチャでは、関数への引数はx86-64ではスタックによって渡されますが、レジスタはその目的で使用されます。

おそらく、x86-64アーキテクチャとx64アーキテクチャのスタック呼び出し規約の違いは、異なる規約が同時に使用されない限り、プログラムスタックの成長に影響を与えない可能性があります。これは、x32関数が他のx32と同じものによって呼び出されるためです。 x64の場合。しかし、ある時点で、関数(おそらくシステム関数)は、いくつかの引数を使用してx86-64マシン用にコードがコンパイルされた関数を呼び出します。この時点で、OS(または他の制御装置)がどのように処理するかについて興味があります。この関数を機能させるため。

前もって感謝します。

4

2 に答える 2

3

i386 / x86-64アーキテクチャが設計されている方法の一部は、CSおよびその他のセグメントレジスタがGDTのエントリを参照することです。GDTエントリには、現在実行中のタスクの動作モードと特権レベルを説明するベースと制限のほかに、いくつかの特別なビットがあります。

CSレジスタが32ビットコードセグメントを参照している場合、プロセッサは基本的にi386互換モードで実行されます。同様に、64ビットコードには64ビットコードセグメントが必要です。

だから、これをすべてまとめます。

OSが32ビットタスクを実行する場合、タスクの切り替え中に、OSは32ビットコードセグメントを参照する値をCSにロードします。割り込みハンドラーにもセグメントレジスタが関連付けられているため、システムコールが発生したり、割り込みが発生したりすると、ハンドラーはOSの64ビットコードセグメント(64ビットOSコードを正しく実行できるようにする)とOSに戻ります。その後、その作業を実行し、新しいタスクのスケジュールを続行できます。

呼び出し規約に関するフォローアップとして。i386もx86-64も、フレームポインタを使用する必要はありません。コードは自由に実行できます。実際、多くのコンパイラ(gcc、clang、VS)は、フレームポインタなしで32ビットコードをコンパイルする機能を提供します。重要なの、呼び出し規約が一貫して実装されていることです。すべてのコードが引数がスタックに渡されることを期待している場合、それは問題ありませんが、呼び出されたコードはそれによく一致します。同様に、レジスタを介して渡すことも問題ありません。全員が同意する必要があります(少なくともライブラリインターフェイスレベルでは、内部関数は通常、好きなように実行できます)。

それを超えて、すべてのプロセスが独自のメモリのプライベートビューを取得するため、2つの違いは実際には問題ではないことに注意してください。ただし、副次的な結果として、プロセスには32ビットコードセグメントまたは64ビットコードがあるため、32ビットアプリは64ビットdllをロードできず、64ビットアプリは32ビットdllをロードできません。セグメント。両方にすることはできません。

于 2012-08-04T23:50:37.177 に答える
1

プロセッサはレガシーモードになっていますが、そのときに実行されるすべてのものが32ビットコードである必要があります。この切り替えはOSによって処理されます。

Windows:WoW64を使用します。WoW64は、プロセッサモードの変更を担当し、互換性のあるdllおよびレジストリ機能も提供します。

Linux:最近まで、Linuxは(Windowsのように)32ビットコードの実行を開始するたびにプロセッサをレガシーモードで実行するように移行していましたが、すべての32ビットglibcライブラリをインストールする必要があり、64ビットコードと連携しようとすると壊れていました。現在、X32 ABIを実装しています。これにより、すべてがスムーズに実行され、32ビットアプリケーションがx64機能にアクセスできるようになります。レジスタの。x32abiに関するこの記事を参照してください

PS:物事の詳細についてはよくわかりませんが、それはあなたに出発点を与えるはずです。

また、この回答とEvan Teranの回答を組み合わせると、発生しているすべてのことの大まかな全体像が得られる可能性があります。

于 2012-08-04T23:49:54.150 に答える