如何加载(mov)类变量到CPU寄存器

how to load (mov) a class variable into cpu register

本文关键字:CPU 寄存器 类变量 mov 加载 何加载      更新时间:2023-10-16

我想加载一个int值定义为类成员eax cpu寄存器。如下所示:

class x
{
    int a;
    x() { a=5; }
    do_stuff()
    {
        __asm
        {
            mov eax, a; // mov a varbiale content into register
        };
    }
};

我如何在任何类中的任何变量中做到这一点?谢谢…

如果您使用的是gcc或icc,这正是您想要的:

class x
{
    int a;
    x() { a=5; }
    do_stuff()
    {
        asm("mov %0, %%eax; // mov a varbiale content into register n"
            :
            : "r" (a)
            : "%eax"
           );

    }
};

如果您仍然感兴趣,可以在http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html上找到关于寄存器约束和淘汰者列表的解释。在MS VC中,我不建议使用内联汇编,因为MS编译器不擅长混合内联汇编和生成汇编,并产生大量开销。

将类变量装入寄存器的最佳方法是让编译器为您完成。

由于编译器总是不得不做最坏的假设,当从内存中读取内容时,它可能被迫多次从类成员中读取值,尽管知道该值没有更改。

例如,在下面的代码中,在函数do_stuff中,编译器不能假设mX的值在调用foo()时是不变的。因此,不允许将其放置在处理器寄存器中。

int glob;
int glob2;
void foo();
class Test
{
public:
  Test(int x) : mX(x) { }
  void do_stuff();
private:
  int mX;
};

void Test::do_stuff()
{
  glob = mX;
  foo();
  glob2 = mX;
}

另一方面,在下面的情况下,源代码的编写使得tmp不能更改函数调用,因此编译器可以安全地将其放置在寄存器中。

void Test::do_stuff()
{
  int tmp = mX;
  glob = tmp;
  foo();
  glob2 = tmp;
}
当涉及到内联汇编器时,我强烈建议您不要使用它。当引入c++时,情况甚至更糟,因为类对象的底层表示不像C结构那样直接(C结构必须完全按照声明的方式在内存中布局)。这意味着类的一个微小变化或迁移到一个新的编译器可能会破坏您的代码。

您需要获得正在处理的类"x"的实例的地址(mov ax,this),以及"a"相对于"x"开头的偏移量(offsetof宏)。

如果您只是添加"a"或"&a"作为do_stuff()函数的参数,这将容易得多。