如何从英特尔的处理器与汇编程序获取随机数?
How I can get the random number from Intel's processor with assembler?
我需要从英特尔处理器中的随机生成器(英特尔酷睿i3)中获取随机数。我不想使用任何图书馆。我想在C++中使用汇编程序粘贴,但我不知道应该使用哪些寄存器和指令。
在支持的CPU(目前只有Ivy Bridge和Haswell Intel CPU)上调用RDRAND
指令会将一个随机值放入指定的寄存器中。例如,这将给你一个随机的64位值:
RDRAND %rax
成功后,将设置进位位。有关更多详细信息,请参阅英特尔的Bull Mountain软件实施指南。("Bull Mountain"是英特尔硬件RNG的代号。)
但我不知道应该使用哪些寄存器和指令。
下面是我在带有GCC的Linux机器上使用的内联汇编程序。我相信我从英特尔手册上撕下了很大一部分。这本书可能是由大卫·约翰斯顿写的,他为研究和问题提供了令人敬畏的技术答案。他也是英特尔设计硬件的人。
int RDRAND_bytes(byte* buff, size_t bsize)
{
if (!HasRDRAND())
return -1;
size_t idx = 0, rem = bsize;
size_t safety = bsize / sizeof(unsigned int) + 4;
unsigned int val;
while (rem > 0 && safety > 0)
{
char rc;
__asm__ volatile(
"rdrand %0 ; setc %1"
: "=r" (val), "=qm" (rc)
);
// 1 = success, 0 = underflow
if (rc)
{
size_t cnt = (rem < sizeof(val) ? rem : sizeof(val));
memcpy(buff + idx, &val, cnt);
rem -= cnt;
idx += cnt;
}
else
{
safety--;
}
}
// Wipe temp on exit
*((volatile unsigned int*)&val) = 0;
// 0 = success; non-0 = failure (possibly partial failure).
return (int)(bsize - rem);
}
下面的代码用于HasRDRAND
。它同时检测AMD和Intel CPU(我认为这是所有提供RDRAND的CPU)。
struct CPUIDinfo {
unsigned int EAX;
unsigned int EBX;
unsigned int ECX;
unsigned int EDX;
};
// Be careful below. EBX/RBX needs to be preserved depending on the memory model and use of PIC.
void cpuid_info(CPUIDinfo *info, const unsigned int func, const unsigned int subfunc) {
__asm__ __volatile__ (
"cpuid"
: "=a"(info->EAX), "=b"(info->EBX), "=c"(info->ECX), "=d"(info->EDX)
: "a"(func), "c"(subfunc)
);
}
int HasAmdCpu() {
CPUIDinfo info;
cpuid_info(&info, 0, 0);
if (memcmp((char *) (&info.EBX), "htuA", 4) == 0
&& memcmp((char *) (&info.EDX), "itne", 4) == 0
&& memcmp((char *) (&info.ECX), "DMAc", 4) == 0) {
return 1;
}
int HasIntelCpu() {
CPUIDinfo info;
cpuid_info(&info, 0, 0);
if (memcmp((char *) (&info.EBX), "Genu", 4) == 0
&& memcmp((char *) (&info.EDX), "ineI", 4) == 0
&& memcmp((char *) (&info.ECX), "ntel", 4) == 0) {
return 1;
}
return 0;
}
int HasRDRAND() {
if (!HasAmdCpu() || !HasIntelCpu())
return 0;
CPUIDinfo info;
cpuid_info(&info, 1, 0);
static const unsigned int RDRAND_FLAG = (1 << 30);
if ((info.ECX & RDRAND_FLAG) == RDRAND_FLAG)
return 1;
return 0;
}
另请参阅如何使用RDRAND内部函数?它不能回答你的直接问题,但它可能是你的一种选择(并可能帮助他人)。
相关文章:
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 整数不会重复超过随机数
- if数组上的随机数
- 如何打开并写入一个名称取自C++中字符串的文件
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 半随机数生成C++
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 有没有办法在 c++ 中同时生成随机数?如果没有,是否有解决方法?
- 具有随机数的二维数组不会更改
- 当我尝试在 Main 中调用插入函数时,它不是取数字?
- 随机数未达到限制
- 我想生成许多矩阵并用随机数填充它
- <random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
- scanf() 只取数字作为输入,避免使用其他字符
- 制作具有平均值的随机数生成器
- 我可以通过取每个数字的模并取和来计算大数的模数吗?
- 为什么 rand 不在我的代码中生成随机数?
- C++ 随机数生成器:尝试将结果作为向量获取,但通过制作 void 函数来执行此操作而出现错误
- 从给定种子生成相同的随机数序列C++
- 如何从英特尔的处理器与汇编程序获取随机数?