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
。ただし、いくつか質問があります。
私の理解では、
fs
16ビットだけです。これは正しいです?値がクアッドワードメモリの場所に移動するとどうなりますか?これは、上位ビットが0に設定されることを意味しますか?__seg
さらに重要なことに、セグメントの開始時に宣言される変数のスコープは、このセグメントに限定されていると思います。では、どのように__seg
役立ちますか?glibc
の作者にはこれを行う正当な理由があると 確信していますが、ソースコードを見てそれが何であるかを理解することはできません。
このコードのアセンブリを生成しようとしましたが、次のようになりましたか?
#APP
# 13 "fs-test.cpp" 1
movl %fs, %eax
# 0 "" 2
#NO_APP
eax
したがって、私の場合は、に使用されたように見え__seg
ます。しかし、それが常に起こっているのか、それとも私がコンパイルした小さなテストファイルで起こったのかはわかりません。それが常に使用されるのであれば、eax
なぜアセンブリはそのように書かれないのでしょうか?__seg
コンパイラが他のレジスタを選択する可能性がある場合、マクロの最後でスコープから外れるため、プログラマはどのレジスタにアクセスするかをどのように知るのでしょうか。最後に、このマクロがglibcソースコードでgrepしたときにどこにも使用されていなかったため、その目的が何であるかについてさらに混乱が生じました。コードが何をしているのか、そしてその理由についての説明はありがたいです。