【发布时间】:2016-01-09 14:40:47
【问题描述】:
我正在尝试使用英特尔的 RDRAND 指令。根据Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2(第 4-298 页),RDRAND 默认生成 32 位随机值,即使在 64 位机器上也是如此:
在 64 位模式下,指令的默认操作大小为 32 位。使用 REX.B 形式的 REX 前缀允许访问其他寄存器 (R8-R15)。
我正在尝试使用rdrandq 强制生成 64 位,但它会产生错误(/tmp/ccLxwW6S.s 是由于使用了内联汇编):
$ g++ -Wall rdrand.cxx -o rdrand.exe
/tmp/ccLxwW6S.s: Assembler messages:
/tmp/ccLxwW6S.s:5141: Error: invalid instruction suffix for `rdrand'
如何在 GCC 下强制使用 64 位版本的 RDRAND 指令? GCC下使用RDRAND时如何设置REX前缀?
提前致谢。
在下面的代码中,output 是一个长度为size 的byte[]。 safety 是一个故障保险。两种不同的字长处理X86, X32, and X64 platforms。
#if BOOL_X86
word32 val;
#else // X32 and X64
word64 val;
#endif
while (size && safety)
{
char rc;
__asm__ volatile(
#if BOOL_X86
"rdrandl %0 ; setc %1"
#else
"rdrandq %0 ; setc %1"
#endif
: "=rm" (val), "=qm" (rc)
:
: "cc"
);
if (rc)
{
size_t count = (size < sizeof(val) ? size : sizeof(val));
memcpy(output, &val, count);
size =- count;
}
else
{
safety--;
}
}
如果我从 RDRAND 中删除显式操作数大小(即,使用 rdrand 而不是 rdrandl 或 rdrandq),则在尝试使用 word64 时会出错:
/tmp/ccbeXOvM.s: Assembler messages:
/tmp/ccbeXOvM.s:5167: Error: operand size mismatch for `rdrand'
【问题讨论】:
-
您是否有任何理由反对使用
_rdrand64_step内在函数? -
@Michael - 我更喜欢内联汇编。 RDRAND 很容易测试。否则,我必须添加额外的测试来包含头文件,并担心不支持 RDRAND 内在函数的 GCC 版本,即使底层处理器和汇编器支持它。
-
显然操作数大小对于
rdrand是隐含的,即使在 AT&T 语法中也是如此。rdrand %e[rr]在使用低位寄存器时没有 REX 前缀,rdrand %r[rr]有。 -
你总是可以写出适当的字节序列:
48 0f c7 f1..
标签: c gcc x86 inline-assembly rdrand