错误:没有此cpu级别的指令(或强制REX前缀)

时间:2015-11-10 13:50:35

标签: assembly x86 nasm linux-x32-abi

我正在使用X32 object file,它使用32位整数,长整数和指针。我像这样建立目标文件:

nasm -f elfx32 rdrand.S -DX32 -o rdrand-x32.o

rdrand.S是多平台(X86,X32和X64)。在X86块中,可以使用64位寄存器。所以我试图(其他代码省略以证明核心问题):

%ifdef X32
  %define  buffer    rdi    ;; x32-abi (http://sites.google.com/site/x32abi/documents)
  %define  size      rsi

  rdrand   rax              ;; generate a 64-bit random value
  mov      [buffer], rax    ;; save it to caller's buffer
%else
  %define  buffer    ...

  rdrand   eax              ;; generate a 32-bit random value
  mov      [buffer], eax    ;; save it to caller's buffer
%endif

但是,看起来NASM 在指令上发出REX前缀,因此导致:

line 100: error: no instruction for this cpu level
line 101: error: no instruction for this cpu level

知道 rdrand rax 工作,因此需要让NASM发出REX前缀。 (我对mov [buffer], rax不确定,但是一旦我弄清楚REX问题,我就会明白这一点。

如何告诉NASM发布宽版本的指令?

我正在使用Debian的NASM版本:

$ nasm -v
NASM version 2.11.05 compiled on Sep  9 2014

但是,我目前在支持X32的内核中

1 个答案:

答案 0 :(得分:1)

%ifdef X32
  rdrand   rax              ;; generate a 64-bit random value
  mov      [buffer], rax    ;; save it to caller's buffer
  ...
%endif

这就是我必须做的事情(搜索NASM的做事方式需要更多的时间,而不是手工发布):

            ;; X32 can use the full register, issue the REX prefix
%ifdef X32
    DB 48h
%endif
            ;; RDRAND is not available prior to Clang 3.2. Just emit
            ;;   the byte codes using DB. This is `rdrand eax`.
    DB 0Fh, 0C7h, 0F0h

然后从rax移动位:

%ifdef X32
    mov        [buffer+4], eax    ;; We can only move 4 at a time
    DB         048h               ;; Combined, these result in 
    shr        eax, 32            ;;   `shr rax, 32`
%endif

    mov        [buffer], eax
    add        buffer, 8          ;; No need for Intel Core 2 slow word workarounds,
    sub        bsize, 8           ;;   like faster adds using `lea buffer,[buffer+8]`