[英]How to set REX prefix when using RDRAND under GCC?
I'm trying to use Intel's RDRAND
instruction. 我正在尝试使用英特尔的
RDRAND
指令。 According to the Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (page 4-298), RDRAND
produces 32-bit random values by default, even on 64-bit machines: 根据英特尔 ®64 和IA-32体系结构软件开发人员手册,第2卷 (第4-298页),即使在64位计算机上,
RDRAND
生成32位随机值:
In 64-bit mode, the instruction's default operation size is 32 bits.
在64位模式下,指令的默认操作大小为32位。 Using a REX prefix in the form of REX.B permits access to additional registers (R8-R15).
使用REX.B形式的REX前缀可以访问其他寄存器(R8-R15)。
I'm trying to force the 64-bit generation using rdrandq
, but its producing an error ( /tmp/ccLxwW6S.s
is due to the use of inline assembly): 我正在尝试使用
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'
How do I force the 64-bit version of the RDRAND instruction under GCC? 如何在GCC下强制使用RDRAND指令的64位版本? How do I set the REX prefix when using RDRAND under GCC?
在GCC下使用RDRAND时,如何设置REX前缀?
Thanks in advance. 提前致谢。
In the code below, output
is a byte[]
with a length of size
. 在下面的代码中,
output
是一个具有size
长度的byte[]
。 safety
is a failsafe. safety
是一种故障安全。 The two different word sizes handle the X86, X32, and X64 platforms . 两种不同的字长可处理X86,X32和X64平台 。
#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--;
}
}
If I remove the explicit operand size from RDRAND (ie, use rdrand
rather than rdrandl
or rdrandq
), then I get an error when attempting to use the word64
: 如果我从RDRAND中删除了显式操作数大小(即,使用
rdrand
而不是rdrandl
或rdrandq
),那么在尝试使用word64
时会出现错误:
/tmp/ccbeXOvM.s: Assembler messages:
/tmp/ccbeXOvM.s:5167: Error: operand size mismatch for `rdrand'
You don't need an operand-size suffix, just use it with a register of the appropriate size (which gcc will select based on the type of the C variable you use). 您不需要操作数大小的后缀,只需将其与适当大小的寄存器一起使用即可(gcc将根据您使用的C变量的类型选择该后缀)。
gcc main.c -o main
(or) (要么)
gcc -m32 main.c -o main
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned int rnd32;
#ifdef __x86_64
long long unsigned int rnd64;
/*
The next instruction generates this asm:
48 0f c7 f0 rdrand %rax
*/
asm volatile("rdrand %0\n":"=r"(rnd64):);
printf("\nRND64=0x%llx\n",rnd64);
#endif
/*
The next instruction generates this asm:
0f c7 f1 rdrand %ecx
*/
asm volatile("rdrand %0\n":"=r"(rnd32):);
printf("RND32=0x%x\n",rnd32);
printf("\nAssembler code:\n\n");
system("objdump -d main|grep rdrand");
return 0;
}
https://repl.it/@zibri/rdrand https://repl.it/@zibri/rdrand
Output (64 bit): 输出(64位):
RND64=0x2f9f0e7d7f209575
RND32=0xbec8ff00
Assembler code:
40054f: 48 0f c7 f0 rdrand %rax
400557: 0f c7 f1 rdrand %ecx
Output (32 bit): 输出(32位):
RND32=0xa3d33766
Assembler code:
59a: 0f c7 f0 rdrand %eax
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.