I’ve been tinkering with inline assembler trying to unite three uncomfortable bed-fellows (GCC, C++, Intel syntax).
Presently, a Google search of the subject line only yields 4 hits, and none answers to the problem. Here are some
snippets from this search and related searches:
…this trick won’t work using Intel syntax…
…You could switch to AT&T syntax. I know that could work. I know AT&T syntax has full support for everything you’re
trying to do…
…As far as I can tell, this can’t work with Intel syntax…
I’d like to set the record straight. Intel syntax can be used in g++ inline assembler to access class members even if it
isn’t documented anywhere how. I provide a 32-bit example:
# include <iostream>
# include <complex>
using namespace std;
//------------------------------------------------------------------------------
class incclass {
public:
incclass(int _val);
void inc();
double pad;
int val;
};
//------------------------------------------------------------------------------
incclass::incclass(int _val = 3.) {
pad = (double)_val;
val = _val;
}
//------------------------------------------------------------------------------
void incclass::inc() {
__asm__ __volatile__(
".intel_syntax noprefix
"
"mov edx, [ebx+%c[_val]]
"
"add edx, 0x01
"
"mov [ebx+%c[_val]], edx
"
".att_syntax prefix
"
:
: "b" (this),
[_val] "i" ((char*)&val-(char*)this)
: "%edx"
);
}
//------------------------------------------------------------------------------
int main(int argc, char* argv])
{
incclass ic = incclass();
cout << "Old value = " << ic.val << endl;
ic.inc();
cout << "New value = " << ic.val << endl;
return 0;
}
//------------------------------------------------------------------------------
Note this must compile with g++ -m32' on 64-bit systems with the 32-bit gcc and stdc libraries available. With the polite prologue and epilogue syntax switches, you don't (and shouldn't) include the
-masm=intel’ option (the C++ file
is called a.cpp):
sh-4.2$ g++ -m32 a.cpp
sh-4.2$ ./a.out
Old value = 3
New value = 4
sh-4.2$
Compiling to assembler…
sh-4.2$ g++ -m32 -S a.cpp
… shows the switch from AT&T syntax to Intel and back within the a.s file:
....
.cfi_offset 3, -12
movl 8(%ebp), %eax
movl %eax, %ebx
#APP
# 31 "a.cpp" 1
.intel_syntax noprefix
mov edx, [ebx+8]
add edx, 0x01
mov [ebx+8], edx
.att_syntax prefix
# 0 "" 2
#NO_APP
popl %ebx
.cfi_restore 3
popl %ebp
....
If anyone’s interested in the (rather exhaustive) information of how I came to this solution or any other of the
specific details, I will try to answer. In the meantime, let it be known that accessing class members in g++ inline
assembler using Intel syntax can be done. And you can tell everyone you saw it first on the openSUSE forums!