gcc内联汇编jmp地址;裸体功能

时间:2013-10-24 22:21:34

标签: c++ c gcc inline-assembly

我可以使用Visual Studio 2012 jmp到一个地址。当谈到gcc / mingw时,我无法判断我的跳转是否正确。

如何跳转到gcc中的地址?

我试过了:

__declspec(naked) void DXHook_D3DPERF_BeginEvent()
{
    #ifdef _MSC_VER  //If using visual studio..
    __asm{jmp[Addr]} //Jump to: Address stored in Addr.
    #else            //else using gcc..
    __asm("jmp *%0"
          : /*No Outputs*/
          : "r" (Addr)
          : "%eax");
    #endif
}

这是对的吗?还有,有办法让gcc停止打扰我:

warning: 'naked' attribute directive ignored.

为什么忽略我的裸属性?

2 个答案:

答案 0 :(得分:1)

TL; DR 在GCC中,这是only available on: ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports

NOT available on x86

Workaround (proposed by Brendon in the comments)

完整答案

(本答案的其余部分假定您使用的是受支持的目标)

这是因为您使用的是Windows属性语法,__declspec和GCC。

来自MSDN reference on __declspec

的引用
  

扩展属性语法简化并标准化了C ++和C ++语言的特定于Microsoft的扩展。

您应该使用GCC function attribute syntax代替或并行使用。

请注意this GCC article的以下引用:

  

注意:Windows和此GCC之间的语义不同   功能 - 例如,__ declspec(dllexport)void(* foo)(void)和   void(__ declspec(dllexport)* foo)(void)意思是完全不同的东西   而这会产生一个关于无法申请的警告   GCC上的非类型属性。

因此,在GCC中使用__declspec语法的方式也可能存在问题(如果它甚至支持它)。

您还应注意,GCC声明它支持的唯一__declspec属性是__declspec(dllexport)(如前面提到的GCC attribute syntax link中所述)。

因此,让我们为您的问题寻找一个通用的解决方案,但首先我们需要阅读实际的GCC attribute syntax并找到以下内容:

  

属性说明符列表可能出现在声明者之前   (以第一个除外)在逗号分隔的声明符列表中   使用单个列表声明多个标识符   说明符和限定符。这些属性说明符仅适用于   它们出现在其声明者之前的标识符。例如,在

 __attribute__((noreturn)) void d0 (void),
     __attribute__((format(printf, 1, 2))) d1 (const char *, ...),
      d2 (void)
     

noreturn属性适用于声明的所有函数;该   format属性仅适用于d1。

因此,您的问题的解决方案将如下所示:

#ifdef __GNUC__
#define ATTRIBUTE_NAKED __attribute__((naked))
#else
#define ATTRIBUTE_NAKED __declspec(naked)
#endif

ATTRIBUTE_NAKED void DXHook_D3DPERF_BeginEvent()
{
    #ifdef _MSC_VER  //If using visual studio..
    __asm{jmp[Addr]} //Jump to: Address stored in Addr.
    #else            //else using gcc..
    __asm("jmp *%0"
          : /*No Outputs*/
          : "r" (Addr)
          : "%eax");
    #endif
}

修改

请务必注意,此属性为platform specific。我引述:

  

     

此属性适用于ARM,AVR,MCORE,MSP430,NDS32,RL78,RX和SPU端口。它允许编译器构造   必要的功能声明,同时允许身体的   函数是汇编代码。指定的功能不会   编译器生成的序言/结尾序列。只有基本的asm   语句可以安全地包含在裸函数中(参见Basic Asm)。   虽然使用扩展的asm或基本的asm和C代码的混合可能   似乎工作,他们不能依赖于可靠和工作   不支持。

引自GCC documentation on function attributes

旁注

可能对clang attributes进行进一步阅读可能有所帮助(大多与GCC兼容),但these comments似乎表明希望与GCC行为相匹配。

答案 1 :(得分:0)

要完成Visual C ++代码的等效操作,请在程序集中完全在单独的文件或顶级(而不是函数)asm语句中实现它。