我试图了解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 时,我没有在任何地方看到这个宏,所以这进一步增加了我对其用途的困惑。任何关于代码在做什么以及为什么的解释都值得赞赏。