简体   繁体   English

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

[英]gcc inlined assembly jmp address; Naked functions

I can jmp to an address using Visual Studio 2012.. When it comes to gcc/mingw, I cannot tell if my jump is correct. 我可以使用Visual Studio 2012跳转到一个地址。当涉及gcc / mingw时,我无法确定跳转是否正确。

How can I jump to an address in gcc? 如何跳转到gcc中的地址?

I tried: 我试过了:

__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
}

Is this correct? 这个对吗? Also, is there a way to get gcc to stop bothering me about: 另外,有没有办法让gcc不再打扰我:

warning: 'naked' attribute directive ignored.

Why does it ignore my naked attribute? 为什么忽略我的裸属性?

TL;DR In GCC, this is only available on: ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports TL; DR在GCC中, 仅适用于:ARM,AVR,MCORE,MSP430,NDS32,RL78,RX和SPU端口

It is NOT available on x86 . x86不可

Workaround (proposed by Brendon in the comments) . 解决方法(由Brendon在评论中提出)

Full answer 完整答案

(The rest of this answer assumes you are using a supported target) (此答案的其余部分假定您使用的是受支持的目标)

That is because you are using the Windows attribute syntax, __declspec with GCC. 那是因为您在GCC中使用Windows属性语法__declspec

Quote from the MSDN reference on __declspec : 引用__declspecMSDN参考

The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages. 扩展属性语法简化并标准化了Microsoft特有的C和C ++语言扩展。

You should use the GCC function attribute syntax instead or in parallel. 您应改为或并行使用GCC函数属性语法

Please also note the following quote from this GCC article : 另请注意此GCC文章的以下引文:

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. 注意:Windows和此GCC功能之间的语义不同-例如,__declspec(dllexport)void(* foo)(void)和void(__declspec(dllexport)* foo)(void)表示的含义完全不同,但这会生成关于无法将属性应用于GCC上非类型的警告。

So there could also be an issue with the way you are using the __declspec syntax in GCC (if it even supports it). 因此,在GCC中使用__declspec语法的方式也可能存在问题(如果它甚至支持的话)。

You should also note that the only __declspec attribute that GCC states it supports is the __declspec(dllexport) (as stated in the already mentioned GCC attribute syntax link ). 您还应该注意,GCC声明支持的唯一__declspec属性是__declspec(dllexport) (如已经提到的GCC属性语法链接中所述 )。

So let's look for a generic solution to your problem but first we will need to read about the actual GCC attribute syntax and find the following: 因此,让我们为您的问题寻找一个通用的解决方案,但是首先,我们需要阅读实际的GCC属性语法并找到以下内容:

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; noreturn属性适用于所有声明的函数; the format attribute only applies to d1. format属性仅适用于d1。

So the solution to your problem would be something like the following: 因此,解决您的问题的方法如下所示:

#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
}

Edit: 编辑:

It is important to note that this attribute is platform specific . 重要的是要注意,此属性是特定平台的 And I quote: 我引用:

naked

This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. 该属性在ARM,AVR,MCORE,MSP430,NDS32,RL78,RX和SPU端口上可用。 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). 裸函数中只能安全地包含基本的asm语句(请参见基本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. 虽然使用扩展asm或基本asm和C代码的混合似乎可以工作,但不能依靠它们可靠地工作并且不受支持。

Quoted from the GCC documentation on function attributes . 引用自GCC文档中的函数属性

Side note 边注

Possible further reading on clang attributes could help (mostly compatible with GCC) but these comments seem to suggest a desire to match GCC behavior. 可能对clang属性进行进一步的阅读可能会有所帮助(大部分与GCC兼容),但是这些注释似乎暗示了人们希望匹配GCC行为。

要执行与Visual C ++代码等效的操作,请在单独的文件中或在顶层asm语句(不在函数中)中完全以汇编形式实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM