5

如果我在 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调用 as 的东西far。但我仍然无法理解如何重现dword ptr

4

1 回答 1

7

您不使用 DWORD PTR 或类似 AT&T 汇编器语法的东西。操作数长度通常取自寄存器名称(可以选择提供带有助记符的后缀),而后者又取自您提供给 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));
}

您可以阅读 GCC 生成的代码(尝试使用 -S 编译)以了解 AT&T 语法。也尝试谷歌一些介绍,如:

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

于 2010-08-10T04:42:51.957 回答