Named Address Spaces for MSVC

Viewed 204

GCC and Clang support a feature called Named Address Space, that allows users to instruct the compiler to generate accesses to certain variables or members through FS or GS register.

Does MSVC support a feature like this?

(I have not been able to find anything on MSDN, but seeing how Windows has long allowed users to change the value of segment registers with FSGSBASE, the compiler must be providing some way to actually arrange the data appropriately, right?)

1 Answers

In MSVC most low-level things are done via intrinsics. Same to this

See x64 (amd64) intrinsics list

To operate on the pointer relative to the base address use

Here's an example

#include <iostream>
#include <intrin.h>
#include <immintrin.h>
#include <cstdint>

int main()
{
    int data[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    
    std::cout << "&data = " << (void*)&data << '\n';
    std::cout << "GS base before                    = " << (void*)_readgsbase_u64() << '\n';

    _writegsbase_u64((uintptr_t)&data);
    std::cout << "GS base after pointing to data[0] = " << (void*)_readgsbase_u64() << '\n';

    std::cout << "GS:[1] = " << __readgsdword(1) << ", GS:[3] = " << __readgsdword(3) << '\n';

    _writegsbase_u64((uintptr_t)&data[7]);
    std::cout << "GS base after pointing to data[7] = " << (void*)_readgsbase_u64() << '\n';

    std::cout << "GS:[0] = " << __readgsdword(0) << ", GS:[2] = " << __readgsdword(2) << '\n';
}

Unfortunately I don't know why in intrin.h the GS functions are only available in 64-bit mode and FS functions are only available in 32-bit mode. Since GS is used for TLS in 64-bit Windows I couldn't change it. Calling _writegsbase_u64 seems to do nothing when I step over the program, the base address is still the same before and after setting. So currently the above code doesn't work on my machine

Related