web-dev-qa-db-ja.com

「FS」/「GS」レジスタの目的は何ですか?

だから、私は次のレジスタとその使用法が何であるかを知っています:

  • CS =コードセグメント(IPに使用)

  • DS =データセグメント(MOVに使用)

  • ES =宛先セグメント(MOVSなどに使用)

  • SS =スタックセグメント(SPに使用)

しかし、次のレジスタは何のために使用されるのですか?

  • FS = "ファイルセグメント"?

  • GS = ???

注:私はnot特定のオペレーティングシステムについて尋ねています-CPUによって使用されることを意図しているものがあれば、それについて尋ねています。

82
Mehrdad

それらが意図されたものがあり、WindowsおよびLinuxで使用されるものがあります。

セグメントレジスタの背後にある当初の意図は、独立した永続的な仮想ストアの一部であることが意図されたメモリの多くの異なる(大きな)セグメントにプログラムがアクセスできるようにすることでした。このアイデアは 1966 Multics operating system からとったもので、ファイルを単なるアドレス可能なメモリセグメントとして扱いました。 BS「ファイルを開く、レコードを書き込む、ファイルを閉じる」はなく、「この値を仮想データセグメントに格納する」だけで、ダーティページフラッシュを行います。

私たちの現在の2010年のオペレーティングシステムは大きく後退しているため、「they官」と呼ばれています。アドレス指定できるのは、yourプロセス空間の単一セグメントのみで、いわゆる「フラット(IMHOのない)アドレス空間」を提供します。 x86-32マシンのセグメントレジスタは、実際のセグメントレジスタに引き続き使用できますが、誰も気にしませんでした(前Intel社長のAndy Groveは、Intelのエンジニア全員がエネルギーを消費し、この機能を実装するための彼のお金、誰もそれを使用するつもりはなかった。

AMDは、64ビットに移行する際に、Multicsを選択から除外してもかまわないと判断しました(慈善的な解釈です;紛れもない解釈は、Multicsについて無知だったためです)。したがって、64ビットモードのセグメントレジスタの一般的な機能を無効にしました。スレッドローカルストアにアクセスするためのスレッドの必要性がまだあり、各スレッドは、ローカルストアをスレッド化するために、ポインタ...すぐにアクセス可能なスレッド状態(レジスタ内など)のどこかに必要でした。 32ビットバージョンでは、WindowsとLinuxの両方がこの目的でFSとGSを使用したため(明確にするためにNickに感謝)、AMDは64ビットセグメントレジスタ(GSとFS)を本質的にこの目的にのみ使用することにしました(できると思います)プロセス空間内の任意の場所を指すようにします(アプリケーションコードがそれらをロードできるかどうかはわからない)。 Intelはパニック状態に陥り、64ビットでAMDの市場シェアを失うことはなく、Andyは引退し、AMDのスキームをそのままコピーすることにしました。

各スレッドのメモリマップにそのスレッドローカルストレージ([セグメント]レジスタポインターは不要!)である絶対仮想アドレス(たとえば、0-FFFなど)を持たせることは、アーキテクチャ上よりきれいでした。 1970年代に8ビットOSでこれを行いました。これは、別の大きなレジスタスタックを使用するように非常に便利でした。

そのため、セグメントレジスタは付録のようになりました。それらは痕跡の目的に役立ちます。集団損失に。

歴史を知らない人々はそれを繰り返す運命にありません。彼らは何か愚かなことをする運命にあります。

90
Ira Baxter

レジスタFSおよびGSはセグメントレジスタです。プロセッサで定義された目的はありませんが、代わりにそれらを実行しているOSによって目的が与えられます。 Windows 64ビットでは、GSレジスタがオペレーティングシステム定義の構造を指すために使用されます。 FSおよびGSは、スレッド固有のメモリにアクセスするためにOSカーネルによって一般的に使用されます。 Windowsでは、GSレジスタを使用して、スレッド固有のメモリを管理します。 LinuxカーネルはGSを使用してCPU固有のメモリにアクセスします。

38
cytinus

[〜#〜] fs [〜#〜]は、Windowsプロセスのスレッド情報ブロック(TIB)を指すために使用されます。

典型的な例の1つは( [〜#〜] seh [〜#〜] )で、コールバック関数へのポインターをFS:[0x00]に格納します。

[〜#〜] gs [〜#〜]は、スレッドローカルストレージ(TLS)へのポインターとして一般的に使用されます。そして、あなたが前に見たかもしれない1つの例は、スタックカナリア保護(stackguard)です、gccでは、このような何かを見るかもしれません:

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax
6
zerocool

Intelマニュアルによると、64ビットモードでは、これらのレジスタは一部の線形アドレス計算で追加のベースレジスタとして使用されることを意図しています。セクション3.7.4.1からこれを引き出しました(4ボリュームセットの86ページ)。通常、CPUがこのモードにある場合、セグメンテーションはこのモードでは使用されないことが多いため、線形アドレスは実効アドレスと同じです。

したがって、このフラットなアドレス空間では、FS&GSはローカルデータだけでなく特定のオペレーティングシステムデータ構造(pg 2793、セクション3.2.4)をアドレス指定する役割を果たします。したがって、これらのレジスタはただし、これらの特定の設計者はオペレーティングシステムによって決定します。

32ビットモードと64ビットモードの両方でオーバーライドを使用する場合、いくつかの興味深いトリックがありますが、これには特権ソフトウェアが関係します。

「オリジナルの意図」の観点から見ると、それは単なる追加の登録であるという以外に言うのは難しいです。 CPUが実アドレスモードの場合、これはプロセッサが高速8086として実行されているようであり、これらのレジスタはプログラムから明示的にアクセスする必要があります。真の8086エミュレーションのために、CPUをvirtual-8086モードで実行し、これらのレジスタは使用されません。

1
Robert Houghton