glibc代码段的目的是什么?

时间:2012-04-10 16:32:26

标签: linux glibc nptl

我想了解tls.h in glibc的以下代码段正在做什么以及为什么:

/* 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. 我的理解是fs只有16位。它是否正确?当值移动到四字记忆位置时会发生什么?这是否意味着高位设置为0?

  2. 更重要的是,我认为在段的开头声明的变量__seg的范围仅限于此段。那么__seg有用吗?我确信glibc的作者有充分的理由这样做,但我无法弄清楚它是如何看待源代码的。

  3. 我尝试为此代码生成程序集,我得到了以下内容?

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

    所以在我的情况下,eax似乎使用了__seg。但我不知道是否总会发生什么,或者它是否只是我编译的小测试文件中发生的事情。如果总是使用eax为什么组装不会这样写?如果编译器可能选择其他寄存器,那么程序员将如何知道访问哪一个,因为__seg超出了宏的末尾范围?最后,当我在glibc源代码中使用它时,我没有看到这个宏在任何地方使用过,所以这进一步增加了我对其目的是什么的困惑。感谢您对代码正在做什么以及为什么做出任何解释。

1 个答案:

答案 0 :(得分:1)

  

我的理解是fs只有16位。它是否正确?当值移动到四字记忆位置时会发生什么?这是否意味着高位设置为0?

  

在段的开头声明的变量__seg仅限于此段。那么__seg如何有用?

你必须阅读GCC statement-expression extension。语句表达式的值是其中最后一个表达式的值。最后的__seg;将毫无用处,除非有人将其分配给其他内容,如下所示:

int foo = TLS_GET_FS();
  

最后,当我在glibc源代码中使用它时,我没有看到这个宏在任何地方使用

TLS_{GET,SET}_FS实际上似乎没有被使用。它们可能在某个版本中使用,然后在删除引用它们的代码时意外遗留。