1

Intel の新しいRDRAND命令を使用する必要がある Visual Studio 2008 IDE で C++ プロジェクトに取り組んでいます。簡単な検索を行ったところ、MSDN はで定義された_rdrand64_stepimmintrin.h組み込み関数を使用することを推奨していますが、これは VS 2008 にはありません。

asm32 ビットのコンパイル済みコードでは、次のようにキーワードを使用して回避できます。

    __asm
    {
        xor eax, eax

        ;RDRAND instruction = Set random value into EAX.
        ;Will set overflow [C] flag if success
        _emit 0x0F
        _emit 0xC7
        _emit 0xF0
    }

ただし、x64asmではサポートされていません。

RDRANDこの命令を使用してプロジェクトを 64 ビット用にコンパイルする方法を教えてください。

4

3 に答える 3

0

うわー、それを理解するのにしばらく時間がかかりました。x64コンパイルのみの Visual Studio 2008 の手順は次のとおりです。

(A)空のプロジェクトを作成します: ファイル -> 新規 -> プロジェクト。次に、[Visual C++] をクリックし、[空のプロジェクト] を選択します。何か名前を付けて、[OK] をクリックして作成します。

(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ます。それを行う場所は2つあります。次に、 を検索しml.exeて変更しml64.exeます。次に、そのファイルを保存してメモ帳を閉じます。

(D) [ソリューション エクスプローラー] でプロジェクトを右クリックし、[カスタム ビルド規則] を選択し、チェックx64 Microsoft Macro Assemblerして [OK] をクリックします。

(E)「ソリューション エクスプローラー」でプロジェクトを右クリックし、[追加] -> [新しい項目] を選択し、拡張子Text File (.txt)を付けて名前を付けます。.asm私はそれを呼びますfuncs_asm_x64.asm。次に、[OK] をクリックします。

(F)funcs_asm_x64.asm x64 asm を開いて入力します。私にとってはRDRAND、64 ビットのオペランドで呼び出すことに興味がありました。私は次のことをしました。この関数は、ランダムなビットで埋められる 64 ビット整数へのポインターとして 1 つのパラメーターを受け取ります。rax成功した場合は 1 を返し、それ以外の場合は 0 を返します。

ここで覚えておくべきことの 1 つは、x64 コードは__fastcall 呼び出し規約のみを使用することです。つまり、関数の最初の 4 つのパラメーターはレジスターで渡されます: RCX、、、および:RDXR8R9

.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、[OK] をクリックして作成します。次に、main.cppファイルに次を追加します。

extern "C" __int64 __fastcall RdRand64(unsigned __int64* pRndVal);

 void main()
{
}

主要部分はextern "C"定義です。main()メソッドは、MASM 要件を満たすために必要です。

(H)次に、[ビルド] -> [構成マネージャー] に移動し、[アクティブなソリューション プラットフォーム] と表示されているドロップダウン リストを開き、[新規] を選択します。次に、「新しいプラットフォームを入力または選択します」で「x64」を選択し、「OK」をクリックします。次に、「アクティブ ソリューション プラットフォーム」として「x64」を選択し、「アクティブ ソリューション構成」で「リリース」を選択します。

(I)構成マネージャー ウィンドウを閉じて、ソリューションをビルドします。成功した場合は、ソリューションのフォルダー内のfuncs_asm_x64.objファイルを探します。そのファイルをメインのソリューション フォルダー (手順\x64\Releaseを使用する必要がある場所) にコピーします。RDRAND

(J)次に、命令を使用する必要があるメイン ソリューションで、RDRAND[ソリューション エクスプローラー] でプロジェクトを右クリックし、[プロパティ] に移動します。次に、Linker -> Command Line に移動し、obj ファイル名を追加します。明らかに、およびのx64プラットフォームに対してのみそうします。私の場合は でした。[OK] をクリックして保存します。DebugReleasefuncs_asm_x64.obj

(K)次に、作成したばかりのこの関数を使用するにextern "C"は、まず最初のプロジェクトと同じように定義を追加します。

extern "C" __int64 __fastcall RdRand64(unsigned __int64* pRndVal);

そして、それをそのまま呼び出すことができます(明らかにインライン化できません):

unsigned __int64 randomNumber = 0;
__int64 bResult = RdRand64(&randomNumber);

(1) 明らかに、上記のすべてがWin32orx86ビルドに必要なわけではありません。そのためには、元の投稿で示したようにインライン アセンブリを使用するだけです。

(2) また、命令がサポートさ__cpuidれていることを確認するためにコマンドを呼び出す必要があることは明らかです。RDRAND多くの CPU では、まだそうではありません。そうでない場合は、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、ステップを保存して、すべてを同じソリューションで実行します。

于 2016-06-27T06:10:09.023 に答える