ASM在C"对于'MOV'&QUOT太多的内存引用; [英] asm in C "too many memory references for `mov'"

查看:2388
本文介绍了ASM在C"对于'MOV'&QUOT太多的内存引用;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过差不多的错误后,但我仍然得到错误:

 为'MOV'太多的内存引用
 前pression后的垃圾`hCPUIDmov缓冲区

...这里的code(MinGW的编译器/ C :: B):

 
    #包括的iostream    使用命名空间std;    工会aregister
    {
        INT的INT;
        无符号位[32];
    };    工会tonibbles
    {
        INT整数;
        短部件[2];
    };    无效GetSerial()
    {
        INT第一部分,第二部分,第三部分;
        aregister则isSupported;
        INT缓冲区;        __asm​​(
            MOV EAX%,01H
            CPUID
            MOV缓冲,EDX
        ); //做CPUID,移动EDX(功能设置寄存器),缓冲
        issupported.theint =缓冲;
        如果(issupported.bits [18])//它被支撑
        {
            __asm​​(
                MOV第一部分,EAX
                MOV EAX%,03H
                CPUID
            ); //移动第一部分为第一部分和呼叫CPUID与下一个子功能得到
            //接下来的64位            __asm​​(
                MOV第二部分,EDX
                MOV PART3,ECX
            ); //现在我们有所有的序列号的96位
            tonibbles串行[3]; //将它分成两个半字节            串行[0] = .integer第一部分; //第一部分
            串行[1] .integer =第2部分; //第二
            串行[2] .integer = 3部分; //第三
        }
    }


解决方案

您组装code是的格式不正确获得GCC。

首先,GCC使用AT& T公司的语法(编辑:默认情况下,由于NRZ ),所以它需要一个添加到每个注册的参考和 $ 立即操作数。目标操作数总是对的右键的一面。

其次,你需要通过一个行分隔符(例如 \\ n \\ t )的新行。由于GCC直接通过您的字符串的汇编,它需要一个特定的语法。

您通常应该尽量减少你的汇编,因为它可能会导致优化问题。以最小化很可能是对出打破CPUID指令成一个函数,并重复使用,需要汇编最简单的方法。

 无效CPUID(int32_t * peax,int32_t * pebx,int32_t * pecx,int32_t * pedx)
{
    __asm​​(
         CPUID
          / *所有输出(EAX,EBX,ECX,EDX)* /
        := A(* peax),= B(* pebx),= C(* pecx),= D(* pedx)
          / *所有的输入(EAX)* /
        :A(* peax)
    );
}

然后,只需简单地调用使用;

  INT A = 1,B,C,D;CPUID(安培; A,和B,和C,和D);

另一个可能更优雅的方式是用做宏的。

I've seen the post about the same error but i'm still get error :

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

... here's the code (mingw compiler / 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
        }
    }

解决方案

Your assembly code is not correctly formatted for gcc.

Firstly, gcc uses AT&T syntax (EDIT: by default, thanks nrz), so it needs a % added for each register reference and a $ for immediate operands. The destination operand is always on the right side.

Secondly, you'll need to pass a line separator (for example \n\t) for a new line. Since gcc passes your string straight to the assembler, it requires a particular syntax.

You should usually try hard to minimize your assembler since it may cause problems for the optimizer. Simplest way to minimize the assembler required would probably be to break the cpuid instruction out into a function, and reuse that.

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)                                           
    );
}

Then just simply call using;

int a=1, b, c, d;

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

Another possibly more elegant way is to do it using macros.

这篇关于ASM在C"对于'MOV'&QUOT太多的内存引用;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆