c++ - gcc内联汇编jmp地址;裸函数

标签 c++ c gcc inline-assembly

我可以使用 Visual Studio 2012 跳转到一个地址。当涉及到 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.

为什么它会忽略我的 naked 属性?

最佳答案

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与海湾合作委员会。

引自MSDN reference on __declspec :

The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages.

你应该使用 GCC function attribute syntax相反或并行。

另请注意以下来自 this GCC article 的引述:

Note: The semantics are not the same between Windows and this GCC feature - for example, __declspec(dllexport) void (*foo)(void) and void (__declspec(dllexport) *foo)(void) mean quite different things whereas this generates a warning about not being able to apply attributes to non-types on GCC.

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

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

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

An attribute specifier list may appear immediately before a declarator (other than the first) in a comma-separated list of declarators in a declaration of more than one identifier using a single list of specifiers and qualifiers. Such attribute specifiers apply only to the identifier before whose declarator they appear. For example, in

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

the noreturn attribute applies to all the functions declared; the format attribute only applies to 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 .我引用:

naked

This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. It allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only basic asm statements can safely be included in naked functions (see Basic Asm). While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.

引自GCC documentation on function attributes .

旁注

可能进一步阅读 clang attributes可能有帮助(主要与 GCC 兼容)但是 these comments似乎暗示了匹配 GCC 行为的愿望。

关于c++ - gcc内联汇编jmp地址;裸函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19577809/

相关文章:

c++ - 是否可以让构造函数具有与声明的类不同的名称?

c++ - 将值传递给 atexit

c - 仅在 C 中使用指针打印字符串数组

我可以两次访问函数返回值而不将其存储在变量中或再次调用函数吗?

c - Linux 上的 vsnwprintf 替代方案

c++ - 添加图像到 QQuickView

C++ WTSQueryUserToken 函数错误

c++ - "Extra ' ; Xcode C++项目' "编译错误

c - 传输编码 : chunked-- Browser does not respond

gcc - 如何在 NASM 中编写 GRUB stage1.S?