Handmade Hero»Forums»Code
Sergio González
35 posts / 1 project
I'm working on Milton, a paint program with infinite canvas. My mom thinks I'm awesome.
__readgsqword only available in kernel mode?
Edited by Sergio González on Reason: s/compiled/worked
Just finished watching episode 182.

I was surprised when the code worked after Casey added __readgsqword() since both the Stack Overflow answer that Google found and the MSDN docs say that this intrinsic is "only available in kernel mode"

Why did it work? Is it simply that MSDN is wrong?
Casey Muratori
801 posts / 1 project
Casey Muratori is a programmer at Molly Rocket on the game 1935 and is the host of the educational programming series Handmade Hero.
__readgsqword only available in kernel mode?
I was pretty surprised by the "only in kernel mode" part myself, because it seemed very clear from our ASM exploration that GetCurrentThreadId() or whatever it was did not transition to Kernel mode to access that segment. So it seems like incorrect documentation to me...

- Casey
Mārtiņš Možeiko
2562 posts / 2 projects
__readgsqword only available in kernel mode?
Probably some artifact left from older Windows or Visual Studio versions.

As Casey told on stream MSVC TLS uses gs register. So it is perfectly valid to access it. Here's example:
1
2
3
4
5
6
__declspec(thread) int ThreadLocalVariable;

int main()
{
  ThreadLocalVariable = 1;
}


Compile it with:
1
cl /O2 /Fa /c tls.c


And look at assembly file tls.asm:
1
2
3
4
5
	mov	ecx, DWORD PTR _tls_index
	mov	rax, QWORD PTR gs:88
	mov	edx, OFFSET FLAT:ThreadLocalVariable
	mov	rax, QWORD PTR [rax+rcx*8]
	mov	DWORD PTR [rdx+rax], 1

It accesses memory location using gs register.
That's for 64-bit code.

For 32-bit code it will use fs register:
1
2
3
4
	mov	ecx, DWORD PTR __tls_index
	mov	eax, DWORD PTR fs:__tls_array
	mov	eax, DWORD PTR [eax+ecx*4]
	mov	DWORD PTR _ThreadLocalVariable[eax], 1


You might want to figure out GetCurrentThreadId works for 32-bit code and wrap our GetThreadID function in #ifdef macro depending on 32-bit/64-bit mode.