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

发布于 2024-10-09 23:07:15 字数 825 浏览 4 评论 0原文

问题:如何从非 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"
  }
};

当前的黑客解决方案:

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 :(
  }
};

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

Question: How can I access a member variable in assembly from within a non-POD class?


Elaboration:

I have written some inline assembly code for a class member function but what eludes me is how to access class member variables. I've tried the offsetof macro but this is a non-POD class.

The current solution I'm using is to assign a pointer from global scope to the member variable but it's a messy solution and I was hoping there was something better that I dont know about.

note: I'm using the G++ compiler. A solution with Intel syntax Asm would be nice but I'll take anything.

example of what I want to do (intel syntax):

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

current hackish solution:

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 :(
  }
};

Those are crude examples but I think they get the point across.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沦落红尘 2024-10-16 23:07:15

这就是您所需要的:

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

编辑添加:汇编器确实接受 Intel 语法,但编译器不知道它,所以这个技巧在使用 Intel 语法时不起作用(不适用于 g++ 4.4.0) , 反正)。

This is all you need:

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

Edited to add: The assembler does accept Intel syntax, but the compiler doesn't know it, so this trick won't work using Intel syntax (not with g++ 4.4.0, anyway).

贪了杯 2024-10-16 23:07:15
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 关键字,并且编译器自行对我的程序集做了奇怪的事情。

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

This might work too, saving you one register:

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

In fact, since the offset of var_j wrt. this should be known at compile time, the second option is the way to go, even if it requires some tweaking to get it working. (I don't have access to a g++ system right now, so I'll leave this up to you to investigate.)

And don't ever underestimate the importance of __volatile__. Took more of my time that I'd liked to track down bugs that appeared because I missed the volatile keyword and the compiler took it upon itself to do strange things with my assembly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文