0

glibcのtls.hからの次のコードセグメントが何をしているのか、そしてその理由を理解しようとしています。

/* Macros to load from and store into segment registers.  */
# define TLS_GET_FS() \
  ({ int __seg; __asm ("movl %%fs, %0" : "=q" (__seg)); __seg; })

fsレジスタに格納されている値をに移動するという基本的な動作は理解できたと思います__seg。ただし、いくつか質問があります。

  1. 私の理解では、fs16ビットだけです。これは正しいです?値がクアッドワードメモリの場所に移動するとどうなりますか?これは、上位ビットが0に設定されることを意味しますか?

  2. __segさらに重要なことに、セグメントの開始時に宣言される変数のスコープは、このセグメントに限定されていると思います。では、どのように__seg役立ちますか?glibcの作者にはこれを行う正当な理由があると 確信していますが、ソースコードを見てそれが何であるかを理解することはできません。

このコードのアセンブリを生成しようとしましたが、次のようになりましたか?

 #APP
 # 13 "fs-test.cpp" 1
 movl %fs, %eax
 # 0 "" 2
 #NO_APP

eaxしたがって、私の場合は、に使用されたように見え__segます。しかし、それが常に起こっているのか、それとも私がコンパイルした小さなテストファイルで起こったのかはわかりません。それが常に使用されるのであれば、eaxなぜアセンブリはそのように書かれないのでしょうか?__segコンパイラが他のレジスタを選択する可能性がある場合、マクロの最後でスコープから外れるため、プログラマはどのレジスタにアクセスするかをどのように知るのでしょうか。最後に、このマクロがglibcソースコードでgrepしたときにどこにも使用されていなかったため、その目的が何であるかについてさらに混乱が生じました。コードが何をしているのか、そしてその理由についての説明はありがたいです。

4

1 に答える 1

1

私の理解では、fsはわずか16ビットです。これは正しいです?値がクアッドワードメモリの場所に移動するとどうなりますか?これは、上位ビットが0に設定されることを意味しますか?

はい。

セグメントの開始時に宣言される変数__segは、このセグメントに制限されます。では、__ segはどのように役立ちますか?

GCCステートメント式拡張について読む必要があります。ステートメント式の値は、その中の最後の式の値です。次の__seg;ように他の何かに割り当てない限り、最後のは役に立たないでしょう。

int foo = TLS_GET_FS();

最後に、glibcのソースコードでこのマクロをgrepしたときに、このマクロがどこでも使用されているのを見ませんでした。

実際には使用TLS_{GET,SET}_FSされていないようです。それらはおそらくいくつかのバージョンで使用されていましたが、それらを参照するコードが削除されたときに誤って残されました。

于 2012-04-12T05:56:43.127 に答える