GCC内联汇编:调用dword ptr

5
如果我在Windows VC++中有以下代码:
DWORD somevar = 0x12345678;
_asm call dword ptr [somevar]

我该如何使用GCC内联汇编,使用AT&T语法制作相同的内容?
__asm__ __volatile__ (
    "call dword ptr [%%edx]" : :
    "d" (somevar)
);

我尝试过类似的方法,但它会产生“垃圾”错误...
然后我试图将somevar传递到某些寄存器中,然后将其转换为dwordptr等,但我无法使其正常工作。
更新:我发现了一些有用的东西,就像在这种情况下似乎我们必须使用括号而不是方括号,并且我找到了一些使用lcall作为far调用的方法。但我仍然无法理解如何复制dword ptr
1个回答

7

使用AT&T汇编语法时不需要使用DWORD PTR或其他类似的操作数长度前缀。操作数长度通常从寄存器名称中提取(也可以在助记符后提供后缀选项),这又取决于您传递给asm()函数的C操作数的大小。内联汇编具有这个非常好的特性,因为它意味着如果您将其编译为x86_64i386架构,则此示例将运行。在第一种情况下,汇编代码变成了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));
}

您可以通过使用-S编译选项来阅读GCC生成的代码,以了解AT&T语法。同时,您也可以尝试搜索一些介绍性的文章,例如:

警告:使用gcc进行内联汇编并非易事。这是因为与大多数其他编译器不同,它是设计为与优化器一起工作的。您必须真正理解约束(“r”)的含义和作用,否则您的代码将会出现无法想象的错误。在您能够回答“早期破坏”是什么之前,请不要考虑使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接