【问题标题】:GCC Inline-assembly: call dword ptrGCC 内联汇编:调用 dword ptr
【发布时间】:2011-03-27 15:17:08
【问题描述】:

如果我在 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

【问题讨论】:

    标签: c++ linux gcc assembly inline-assembly


    【解决方案1】:

    在 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));
    }
    

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

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

    【讨论】:

      猜你喜欢
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多