【发布时间】:2017-08-09 23:23:41
【问题描述】:
作为尝试实现对 cgo 的 msvc 支持的一部分,我发现我需要将一些内联 gcc 程序集移植到 ml64。这是原始程序集:
ts = *(ThreadStart*)v;
/*
* Set specific keys in thread local storage.
*/
__asm {
"movq %0, %%gs:0x28\n" // MOVL tls0, 0x28(GS)
"movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp
"movq %1, 0(%%rax)\n" // MOVQ g, 0(GS)
:: "r"(ts.tls), "r"(ts.g) : "%rax"
}
这是我创建的外部汇编文件:
PUBLIC msvc_windows_amd64_threadentry
.CODE
msvc_windows_amd64_threadentry PROC
MOV gs:[0x28], ts.tls
MOV rax, gs:[0x28]
MOV gs:[0], ts.g
ret
msvc_windows_amd64_threadentry ENDP
END
显然存在一些问题。一方面,我现在不知道如何让汇编器知道ts 的结构; gcc 显然知道它,因为它在正在编译的文件中,但 msvc 不支持 amd64 内联汇编。另一个是我认为我可以像其他任何extern 函数一样调用msvc_windows_amd64_threadentry,但我并不完全确定。老实说,我从来没有过多地处理装配问题,所以我以前从未遇到过这些问题。
【问题讨论】:
-
您遇到的主要问题是这是针对 linux 线程本地存储的。 Windows 线程本地存储完全不同,因此即使您可以让该程序集与您的编译器一起使用,它也不会在 Windows 上运行。
-
完全取决于你想要做什么。如果您不介意依赖 C11,请重写代码以使用
thread_local。 -
“原始程序集”示例中的内联程序集过于复杂。只有第一个汇编语句需要在内联汇编中,最后两个语句可以用纯 C 编码。第三个语句也与同一行给出的注释不匹配。
-
实际上,澄清一下,当我说“gcc”时,我指的是 MinGW,似乎 GS 用于 win_amd64 上的线程本地存储。您确定这不会在 Windows 上正常运行吗?我认为 MinGW 还不够先进,无法重写程序集。
-
你知道原始代码是否真的可以在Windows上运行吗?看起来写它的人不太清楚自己在做什么。
标签: c gcc assembly visual-c++