Ничего себе, мне потребовалось некоторое время, чтобы понять это. Вот шаги для Visual Studio 2008 для x64
только для компиляции:
(A) Создайте пустой проект: Файл -> Создать -> Проект. Затем нажмите «Visual C++» и выберите «Empty Project». Назовите это что-нибудь и нажмите «ОК», чтобы создать.
(B) Перейти в папку установки VS, в моем случае это был C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\VCProjectDefaults
и скопировать masm.rules
файл и назовите его masm64.rules
(C) Открыть masm64.rules
в блокноте и поиск Microsoft Macro Assembler
и изменить его до x64 Microsoft Macro Assembler
. Для этого будет два места. Затем найдите ml.exe
и измените его на ml64.exe
. Затем сохраните этот файл и закройте Блокнот.
(D) Щелкните правой кнопкой мыши проект в «Обозревателе решений» и выберите «Пользовательские правила сборки» и установите флажок x64 Microsoft Macro Assembler
и нажмите «ОК».
(E) правой кнопкой мыши проект в обозревателе решений «» и выберите Add -> New Item выберите Text File (.txt)
и назовите его что-то с .asm
расширением. Я назову это funcs_asm_x64.asm
. Затем нажмите «ОК».
(F) Открыть funcs_asm_x64.asm
и набрать x64 asm. Для меня мне было интересно позвонить RDRAND
с 64-битным операндом. Я сделал следующее. Эта функция примет один параметр в качестве указателя на 64-битное целое число, которое будет заполнено случайными битами. Он вернет 1 в rax
если успех, иначе он вернет 0.
Одна вещь, чтобы помнить, что x64-код использует только __fastcall
calling convention, а это означает, что первые 4 параметра для функции передаются в регистрах: RCX
, RDX
, R8
и R9
:
.code
RdRand64 PROC
; RCX = pointer to receive random 64-bit value
; RETURN: [RAX] = 1 if success, 0 if failed
xor rax, rax
test rcx, rcx
jz lbl_out
;push rdx
xor rdx, rdx
DB 048h, 0fh, 0c7h, 0f2h ;RDRAND RDX
setc al
mov [rcx], rdx
;pop rdx
lbl_out:
ret
RdRand64 ENDP
END
(G) Затем щелкните правой кнопкой мыши проект в «Обозревателе решений» и выберите «Добавить» - «Новый элемент», выберите C++ File (.cpp)
и назовите его main.cpp
и нажмите «ОК», чтобы создать. Затем добавьте следующую строку в файл main.cpp
:
extern "C" __int64 __fastcall RdRand64(unsigned __int64* pRndVal);
void main()
{
}
Основная часть является extern "C"
определение. main()
необходим для удовлетворения требований MASM.
(H) Затем перейдите в сборку -> Диспетчер конфигурации и откройте раскрывающийся список, где указано «Активная платформа решений», и выберите «Создать». Затем выберите «x64» в «Тип или выберите новую платформу» и нажмите «ОК». Затем выберите «x64» как «Активная платформа решений», а также выберите «Отпустить» в «Конфигурация активного решения».
(I) Закрыть окно диспетчера конфигурации и построить решение. Если вам удалось найти файл funcs_asm_x64.obj
в папке \x64\Release
для вашего решения. Скопируйте этот файл в основную папку решения (где вы, необходимые для использования RDRAND
инструкции.)
(J) Тогда в главном решении, где вам необходимо использовать RDRAND
инструкции, щелкните правой кнопкой мыши на проект в «обозревателе решений »и перейдите в« Свойства ». Затем перейдите в Linker -> Command Line и добавьте свое имя файла obj. Очевидно, что это делается только для платформы x64
для Debug
и Release
. В моем случае это было funcs_asm_x64.obj
. Нажмите «ОК» для сохранения.
(K) Тогда, чтобы использовать эту функцию, что я только что создали, первый добавить extern "C"
определение так же, как вы имели в первом проекте:
extern "C" __int64 __fastcall RdRand64(unsigned __int64* pRndVal);
, а затем вы можете назвать его как таковой (очевидно, она не может быть встраиваемыми):
unsigned __int64 randomNumber = 0;
__int64 bResult = RdRand64(&randomNumber);
(1) Очевидно, что все вышесказанное не является необходимым для Win32
или x86
сборка. Для этого просто используйте встроенную сборку, как я показал в своем оригинальном посте.
(2) Также необходимо выполнить команду __cpuid
, чтобы гарантировать, что инструкция RDRAND
поддерживается. На многих процессорах это еще не так. Поэтому, если это не так, тогда не вызывайте мой метод RdRand64
, так как он сработает! Вы можете использовать этот код, чтобы проверить и сохранить результат где-то в глобальной переменной:
#include <intrin.h>
bool is_RDRAND_supported()
{
int name[4] = {0};
__cpuid(name, 0);
if(name[1] == 0x756e6547 && //uneG
name[2] == 0x6c65746e && //letn
name[3] == 0x49656e69) //Ieni
{
int data[4] = {0};
__cpuid(data, 1);
//Check bit 30 on the 2nd index (ECX register)
if(data[2] & (0x1 << 30))
{
//Supported!
return true;
}
}
return false;
}
(3) Существует способ включить asm
файл в том же проекте в VS 2008
. К сожалению, если вы это сделаете, вы не сможете переключить проект обратно на Win32
и скомпилировать, если вам нужно.Поэтому, если вы компилируете его только для x64
, сохраните шаг и сделайте все это в том же решении.
С отключенным asm больше не существует способа использовать новые операционные системы со старыми компиляторами. Вы * можете * компилировать один отдельный файл объекта отдельно, хотя и затем связывать его, хотя ... – o11c
Может ли кто-то с более поздней версией VS (2012 и выше) скопировать и вставить внутреннее определение для '_rdrand64_step'? Или он поставляется с отдельным двоичным файлом? – c00000fd
@ c00000fd Это неотъемлемая часть. Нет определения. Вот что такое внутреннее средство. – immibis