views:

97

answers:

1

Hello. If I have the following code in Windows VC++:

DWORD somevar = 0x12345678;
_asm call dword ptr [somevar]

How can I make the same thing in GCC inline-assembly, with AT&T syntax?

__asm__ __volatile__ (
    "call dword ptr [%%edx]" : :
    "d" (somevar)
);

I've tried something like this, but it generates an "junk" error...

And then I tried to pass somevar to some registers, and then convert it to dword, ptr, etc, but I can't get it to work.

Thanks in advance.

UPDATE: I found something that would be useful, like it seems that we have to use parenthesis instead of brackets in that case, and I found something with lcall to call as far. But I still can't understand how I can reproduce dword ptr.

+3  A: 

You don't use DWORD PTR or anything like this with the AT&T assembler syntax. The operand length is usually taken from the register name (there's an option of provide a suffix with the mnemonic), which in turn comes from the size of the C operand you give to asm(). This is a very nice property of the inline assembler because it means that this example runs if you compile it for the x86_64 or the i386 architecture. In the first case, the assembly becomes something like call *%rdx, in the second case it becomes call *%edx:

#include <stdio.h>
void p()
{
    puts("Hallo");
}
typedef void (*fp)();
int main()
{
    fp var=&p;
    var();  
    // put 'var' in a register, the '*' says call indirect:
    asm volatile ("call *%0"::"r"(var));
}

You can read the code GCC generates (try compiling with the -S) in order to learn the AT&T syntax. Also try to google some intro, like:

WARNING: Inline assembly with gcc is not a trivial matter. This is because, other than with most other compilers, it is designed to work with the optimizer. You have to really understand what the constraints ("r") mean and do, or else you will break your code in ways you can't imagine. Don't even think about using it before you can answer what an "early clobber" is.

Luther Blissett