2015-11-10 1 views
1

Я работаю над X32 object file, в котором используются 32-битные целые числа, длинные и указатели. Я строю объектный файл так:Ошибка: нет инструкции для этого уровня процессора (или, префикс REX)

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

rdrand.S мульти-platofrm (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 ядра в данный момент.

+0

My nasm version 2.10.01 правильно испускает префикс rex и не имеет проблем с этим кодом. Также протестировано с 2.11.08, которое отлично работает. – Jester

+0

@Jester - я добавил информацию о версии на вопрос. Я дважды проверил результаты. Какие флаги вы используете для ассемблера? – jww

+0

Я использовал вашу командную строку. Протестировано только с debian 2.11.05. И я тоже не в X32, хотя я не думаю, что это имеет значение. Я определил «буфер», чтобы собрать его. – Jester

ответ

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]`