首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC下使用RDRAND时如何设置REX前缀?

GCC下使用RDRAND时如何设置REX前缀?
EN

Stack Overflow用户
提问于 2015-10-12 07:39:46
回答 1查看 801关注 0票数 1

我正在尝试使用英特尔的RDRAND指令。根据Intel 64和IA-32架构软件开发人员手册,第2卷 (第4-298页),RDRAND在默认情况下产生32位随机值,甚至在64位机器上也是如此:

在64位模式下,指令的默认操作大小为32位.使用REX前缀REX.B允许访问其他寄存器(R8-R15)。

我试图使用rdrandq强制64位生成,但是它产生了一个错误(/tmp/ccLxwW6S.s是由于使用内联程序集):

代码语言:javascript
复制
$ 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是一个长度为sizebyte[]safety是一个故障安全机制。两个不同的单词大小处理X86、X32和X64平台

代码语言:javascript
复制
#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而不是rdrandlrdrandq),则在尝试使用word64时会出现错误。

代码语言:javascript
复制
/tmp/ccbeXOvM.s: Assembler messages:
/tmp/ccbeXOvM.s:5167: Error: operand size mismatch for `rdrand'
EN

回答 1

Stack Overflow用户

发布于 2019-03-22 09:24:20

您不需要操作数大小的后缀,只需将其与适当大小的寄存器一起使用( gcc将根据您使用的C变量的类型选择它)。

代码语言:javascript
复制
gcc main.c -o main

(或)

代码语言:javascript
复制
gcc -m32 main.c -o main
代码语言:javascript
复制
#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

输出(64位):

代码语言:javascript
复制
RND64=0x2f9f0e7d7f209575
RND32=0xbec8ff00

Assembler code:

   40054f:   48 0f c7 f0             rdrand %rax   
   400557:   0f c7 f1                rdrand %ecx

输出(32位):

代码语言:javascript
复制
RND32=0xa3d33766

Assembler code:

  59a:  0f c7 f0                rdrand %eax
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33075694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档