Accessing C++ class member in inline assembly

2019-02-27 18:35发布

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.

2条回答
手持菜刀,她持情操
2楼-- · 2019-02-27 18:48
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.

查看更多
贪生不怕死
3楼-- · 2019-02-27 18:52

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).

查看更多
登录 后发表回答