3

I used this instruction in Visual C++ inline assembly

lea eax, FS:[0]

Why did eax get a zero?

And how do I get the linear address of FS:[0]?

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
Zhibo Shen
  • 135
  • 7
  • Updated to ask [what the OP really wanted to know](https://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction/47589203?noredirect=1#comment82135841_47589203) – Peter Cordes Dec 01 '17 at 08:35
  • 1
    Normally, some type of operating system call is needed to map such an address into a process / thread's flat virtual address space. – rcgldr Dec 01 '17 at 08:37
  • 2
    In 64-bit mode, use [`RDFSBASE eax`](http://felixcloutier.com/x86/RDFSBASE:RDGSBASE.html) if it's available on your CPU. But unfortunately that instruction is not available in 32-bit mode, and it's not baseline for x86-64 either; there's a CPUID feature bit for it. (And using MSVC inline-asm restricts you to only 32-bit code.) – Peter Cordes Dec 01 '17 at 08:39

2 Answers2

6

Assuming FS points to the Windows Thread Information Block (TIB), also known as the Thread Environment Block (TEB), you get the linear address of the TIB by reading the 32-bit value at fs:[0x18]. The best way to do this in Visual C++ is to use the __readfsdword intrinsic:

TEB *teb = (TEB *) __readfsdword(0x18);
Ross Ridge
  • 37,034
  • 7
  • 72
  • 110
3

The LEA instruction ("Load Effective Address") is badly named (e.g. should probably be called LEO/"Load Effective Offset") because it only calculates the offset within a segment.

Brendan
  • 31,872
  • 2
  • 33
  • 57