用户空间程序如何在64位Windows(当前为XP-64)下配置"GS:"?
(通过configure,将GS:0设置为任意64位线性地址).
我正在尝试将"JIT"环境移植到最初为Win32开发的X86-64.
一个不幸的设计方面是相同的代码需要在多个用户空间线程(例如,"光纤")上运行.代码的Win32版本使用GS选择器,并生成正确的前缀来访问本地数据 - "mov eax,GS:[offset]"指向当前任务的正确数据.来自Win32版本的代码会将值加载到GS中,只要它有一个可以工作的值.
到目前为止,我已经能够发现64位窗口不支持LDT,因此Win32下使用的方法不起作用.但是,X86-64指令集包括"SWAPGS",以及在不使用传统分段的情况下加载GS的方法 - 但这仅适用于内核空间.
根据X64手册,即使Win64允许访问描述符 - 它没有 - 但是没有办法设置段基的高32位.设置这些的唯一方法是通过GS_BASE_MSR(和相应的FS_BASE_MSR - 在64位模式下忽略其他段基).WRMSR指令是Ring0,所以我不能直接使用它.
我希望有一个Zw*函数,允许我在用户空间或Windows API的其他一些黑暗角落中更改"GS:".我相信Windows仍然使用FS:对于自己的TLS,所以必须有一些机制?
程序在XP-32上显示"PASS",在XP-x64上不显示.
#include <windows.h>
#include <string.h>
#include <stdio.h>
unsigned char GetDS32[] =
{0x8C,0xD8, // mov eax, ds
0xC3}; // ret
unsigned char SetGS32[] =
{0x8E,0x6C,0x24,0x04, // mov gs, ss:[sp+4]
0xC3 }; // ret
unsigned char UseGS32[] =
{ 0x8B,0x44,0x24,0x04, // mov eax, ss:[sp+4]
0x65,0x8B,0x00, // mov eax, gs:[eax]
0xc3 }; // ret
unsigned char SetGS64[] =
{0x8E,0xe9, // mov …Run Code Online (Sandbox Code Playgroud) 是否有算法可以计算重复小数比的数字而不从头开始?
我正在寻找一种不使用任意大小的整数的解决方案,因为这适用于十进制扩展可能任意长的情况.
例如,33/59扩展为58位的重复小数.如果我想验证,我怎么能计算从第58位开始的数字?
编辑 - 比率2124679/2147483647,如何获得2147484600th到2147484700位的百位数.
给定函数y = f(A,X):
unsigned long F(unsigned long A, unsigned long x) {
return ((unsigned long long)A*X)%4294967295;
}
Run Code Online (Sandbox Code Playgroud)
对于'x'的所有值,我如何找到反函数x = g(A,y)使得x = g(A,f(A,x))?
如果f()对于'x'的所有值都不可逆,那么最接近逆的是什么?
(F是一个过时的PRNG,我试图理解一个人如何反转这样的功能).