我可以使用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.
为什么忽略我的裸属性?
答案 0 :(得分:1)
TL; DR 在GCC中,这是only available on: ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports
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
语句中实现它。