C++ GCC内联程序集:调用dword ptr

C++ GCC内联程序集:调用dword ptr,c++,linux,gcc,assembly,inline-assembly,C++,Linux,Gcc,Assembly,Inline Assembly,如果我在Windows VC++中有以下代码: DWORD somevar = 0x12345678; _asm call dword ptr [somevar] 如何使用AT&T语法在GCC内联汇编中实现相同的功能 __asm__ __volatile__ ( "call dword ptr [%%edx]" : : "d" (somevar) ); 我尝试过类似的方法,但它会产生一个“垃圾”错误 然后我尝试将somevar传递到一些寄存器,然后将其转换为dword,ptr

如果我在Windows VC++中有以下代码:

DWORD somevar = 0x12345678;
_asm call dword ptr [somevar]
如何使用AT&T语法在GCC内联汇编中实现相同的功能

__asm__ __volatile__ (
    "call dword ptr [%%edx]" : :
    "d" (somevar)
);
我尝试过类似的方法,但它会产生一个“垃圾”错误

然后我尝试将
somevar
传递到一些寄存器,然后将其转换为
dword
ptr
,等等,但我无法让它工作


更新:我发现了一些有用的东西,好像在这种情况下我们必须使用括号而不是括号,并且我发现了一些带有
lcall
的东西,称为
far
。但我仍然不明白如何重现dword ptr

您在AT&t汇编程序语法中不使用dword ptr或类似的东西。操作数长度通常取自寄存器名(有一个选项可以提供带助记符的后缀),而助记符名又来自于给asm()的C操作数的大小。这是内联汇编程序的一个非常好的属性,因为这意味着如果您为x86_64或i386体系结构编译此示例,它将运行。在第一种情况下,程序集变成类似于
call*%rdx
,在第二种情况下变成
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));
}
#包括
void p()
{
看跌期权(“哈罗”);
}
typedef void(*fp)();
int main()
{
fp var=&p;
var();
//将“var”放入寄存器中,“*”表示调用间接:
asm volatile(“调用*%0”:“r”(var));
}
您可以阅读GCC生成的代码(尝试使用-S编译),以了解AT&T语法。也可以在谷歌上搜索一些介绍,比如:

警告:带有gcc的内联程序集不是一件小事。这是因为,与大多数其他编译器不同,它被设计为与优化器一起工作。您必须真正理解约束(“r”)的含义和作用,否则您将以无法想象的方式破坏代码。在你能回答什么是“早期打击者”之前,甚至不要考虑使用它