2012-01-10 66 views
3

我想在内联汇编中使用线程局部变量,但是当我看到汇编代码时,看起来编译器不会生成正确的代码。对于下面的内嵌代码,其中saved_sp全球声明为__thread long saved_sp线程局部变量和内联汇编

__asm__ __volatile__ (
     "movq %rsp, saved_sp\n\t"); 

拆卸如下所示。

mov %rsp,0x612008 

这显然是不正确的事情,因为我知道,GCC使用FS段的线程局部变量。它应该产生像

mov %rsp, fs:somevalue 

它不是。为什么?在内联汇编中使用线程局部变量是否有问题?

+0

我并不认为海合会无论如何修改你的内联汇编代码。很可能你必须明确指定段覆盖前缀。尝试在'“movq%rsp,saved_sp \ n \ t”'之前插入'“.byte 0x64 \ n \ t”'。 – 2012-01-10 22:04:00

回答

4

一个简单的事情,肯定会工作是采取一个指针的线程局部变量,并写入它。
您的编译器肯定会正确执行long *saved_fp_p = &saved_fp,并且内联汇编将只处理saved_fp_p,这是一个局部变量。

您也可以使用gcc的输入和输出语法:

__asm__ __volatile__ (
    "mov %%rsp, 0(%0)" : : "r" (&saved_sp) 
); 

这让负责解决saved_fp的地址的编译器和汇编代码得到它在寄存器中。

我们发现,这也适用,

__asm__ __volatile__ asm ("mov %rsp,%0" : "=m" (saved_sp)) 
+0

这是一个很好的解决方案,但我更愿意直接写入saved_sp,而不是使用寄存器指向它。 – MetallicPriest 2012-01-10 22:21:49

+1

也许'asm(“mov%rsp,%0”::“m”(saved_fp))'会起作用。重要的部分是让编译器而不是汇编程序处理saved_fp变量。编译器肯定可以做到,汇编似乎做得很糟糕。 – ugoren 2012-01-10 22:32:09

+0

这确实有效!谢谢! – MetallicPriest 2012-01-10 22:46:40