在内联汇编中访问C ++类成员

时间:2011-01-03 09:18:16

标签: c++ assembly g++ inline-assembly

问题:如何从非POD类中访问程序集中的成员变量?


精化:

我已经为类成员函数编写了一些内联汇编代码,但是我想到的是如何访问类成员变量。我已经尝试了 offsetof 宏,但这是一个非POD类。

我正在使用的当前解决方案是将指向全局范围的指针分配给成员变量,但这是一个混乱的解决方案,我希望有更好的东西,我不知道。

注意:我正在使用G ++编译器。使用英特尔语法Asm的解决方案会很好但我会采取任何措施。

我想做的例子(英特尔语法):

class SomeClass
{
  int* var_j;
  void set4(void)
  {
    asm("mov var_j, 4"); // sets pointer SomeClass::var_j to address "4"
  }
};

当前的hackish解决方案:

int* global_j;
class SomeClass
{
  int* var_j;
  void set4(void)
  {
    asm("mov global_j, 4"); // sets pointer global_j to address "4"
    var_j = global_j;       // copy it back to member variable :(
  }
};

这些都是粗略的例子,但我认为他们明白了这一点。

2 个答案:

答案 0 :(得分:6)

这就是你所需要的:

__asm__ __volatile__ ("movl $4,%[v]" : [v] "+m" (var_j)) ;

编辑添加:汇编程序确实接受英特尔语法,但编译器不知道它,所以这个技巧不能使用英特尔语法(不管是g ++ 4.4.0)

答案 1 :(得分:3)

class SomeClass
{
  int* var_j;
  void set4(void)
  {
    __asm__ __volatile__("movl $4, (%0,%1)"
:
: "r"(this), "r"((char*)&var_j-(char*)this)
:
);
  }
};

这也可能有用,为您节省一个寄存器:

    __asm__ __volatile__("movl $4, %1(%0)"
:
: "r"(this), "i"((char*)&var_j-(char*)this)
:
);

事实上,由于var_j wrt的偏移。 this应该在编译时知道,第二个选项是要走的路,即使它需要一些调整才能使它工作。 (我现在无法访问g ++系统,因此我会留待您进行调查。)

并且永远不要低估__volatile__的重要性。花了我更多的时间,我想要追踪出现的错误,因为我错过了volatile关键字,并且编译器自己用它来装配奇怪的东西。