11

同じエラーに関する投稿を見ましたが、まだエラーが発生します:

 too many memory references for `mov'
 junk `hCPUIDmov buffer' after expression

...コードは次のとおりです(mingwコンパイラ/ C :: B):


    #include iostream

    using namespace std;

    union aregister
    {
        int theint;
        unsigned bits[32];
    };

    union tonibbles
    {
        int integer;
        short parts[2];
    };

    void GetSerial()
    {
        int part1,part2,part3;
        aregister issupported;
        int buffer;

        __asm(
            "mov %eax, 01h"
            "CPUID"
            "mov buffer, edx"
        );//do the cpuid, move the edx (feature set register) to "buffer"


        issupported.theint = buffer;
        if(issupported.bits[18])//it is supported
        {
            __asm(
                "mov part1, eax"
                "mov %eax, 03h"
                "CPUID"
            );//move the first part into "part1" and call cpuid with the next subfunction to get
            //the next 64 bits

            __asm(
                "mov part2, edx"
                "mov part3, ecx"
            );//now we have all the 96 bits of the serial number


            tonibbles serial[3];//to split it up into two nibbles

            serial[0].integer = part1;//first part
            serial[1].integer = part2;//second
            serial[2].integer = part3;//third
        }
    }

4

2 に答える 2

16

アセンブリ コードがgcc 用に正しくフォーマットされていません。

まず、gcc は AT&T 構文を使用するため (編集:デフォルトでは nrz に感謝%)、レジスタ参照ごとに a を追加し$、即値オペランドには a を追加する必要があります。デスティネーション オペランドは常に右側にあります。

次に、改行のために行セパレーター (例えば\n\t) を渡す必要があります。gcc は文字列を直接アセンブラーに渡すため、特定の構文が必要です。

オプティマイザに問題が発生する可能性があるため、通常はアセンブラを最小限に抑えるように努力する必要があります。必要なアセンブラを最小限に抑える最も簡単な方法は、おそらく cpuid 命令を関数に分割し、それを再利用することです。

void cpuid(int32_t *peax, int32_t *pebx, int32_t *pecx, int32_t *pedx)
{
    __asm(
         "CPUID"
          /* All outputs (eax, ebx, ecx, edx) */
        : "=a"(*peax), "=b"(*pebx), "=c"(*pecx), "=d"(*pedx)   
          /* All inputs (eax) */
        : "a"(*peax)                                           
    );
}

次に、単に using; を呼び出すだけです。

int a=1, b, c, d;

cpuid(&a, &b, &c, &d);

もう 1 つのおそらくより洗練された方法は、マクロを使用することです。

于 2013-02-23T00:22:30.610 に答える