CHE
CHE

Reputation: 3

How do I get address of class member function by asm in GCC?

guys! I have a problem. How do I get address of class member function by asm in GCC?

In VS2012, we can do below code to get address.

asm {mov eax, offset TEST::foo}

But, in GCC?

__asm__ __volatile__(
                     "movq offset %1, %%rdi"
                     "movq %%rdi, %0"
                     :"=r"(addr)
                     :"r"(&TEST::foo)
);

It failed...

Upvotes: 0

Views: 621

Answers (1)

Peter Cordes
Peter Cordes

Reputation: 365257

AT&T syntax doesn't use the offset keyword. And besides, you've asked the compiler to put &TEST::foo in a register already.

__asm__ (
                 "mov %1, %0"
                 :"=r"(addr)
                 :"r"(&TEST::foo)
);

Or better:

__asm__ ( ""                // no instructions
          :"=r"(addr)
          :"0"(&TEST::foo)  // same register as operand 0
);

Or even better: addr = &TEST::foo; https://gcc.gnu.org/wiki/DontUseInlineAsm for this, because it stops the compiler from knowing what's going on.

But if you are going to use inline asm, make sure you let the compiler do as much for you as it can. Use constraints to tell it where you want the input, and where you left the output. If the first or last instruction of an inline-asm statement is a mov, usually that means you're doing it wrong. (See the tag wiki for some links to guides on how to write GNU C inline asm that doesn't suck.


Bugs in your original: you didn't declare a clobber on RDI, so the compiler will still assume you didn't modify it.

You don't need volatile if the only reason to run the code in the asm statement is to produce the output operands, not for side effects. Leaving out volatile lets the compiler optimize around it, and even drop it entirely if the output is unused.

Upvotes: 1

Related Questions