GCC 内联程序集 JMP 地址;裸函数
gcc inlined assembly jmp address; Naked functions
我可以使用Visual Studio 2012jmp到一个地址。当谈到 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.
为什么它忽略了我的裸属性?
TL;DR 在 GCC 中,这仅适用于:ARM、AVR、MCORE、MSP430、NDS32、RL78、RX 和 SPU 端口
它在 x86 上不可用。
解决方法(由布伦登在评论中提出)。
完整答案
(本答案的其余部分假设您使用的是受支持的目标)
这是因为您使用的是 Windows 属性语法,__declspec
使用 GCC。
引用MSDN关于__declspec
的参考:
扩展属性语法简化并标准化了 C 和 C++ 语言的特定于Microsoft的扩展。
您应该改用或并行使用 GCC 函数属性语法。
另请注意这篇 GCC 文章中的以下引述:
注意:Windows和此GCC之间的语义不同 功能 - 例如,__declspec(dllexport) void (*foo)(void) 和 void (__declspec(dllexport) *foo)(void) 的意思完全不同 而这会生成有关无法应用的警告 GCC 上非类型的属性。
因此,您在 GCC 中使用 __declspec
语法的方式也可能存在问题(如果它甚至支持它)。
您还应该注意,GCC 声明它支持的唯一__declspec
属性是__declspec(dllexport)
(如已经提到的 GCC 属性语法链接中所述)。
因此,让我们为您的问题寻找一个通用解决方案,但首先我们需要阅读实际的 GCC 属性语法并找到以下内容:
属性说明符列表可能紧挨着声明符出现 (第一个除外)在逗号分隔的声明符列表中 使用单个列表声明多个标识符 说明符和限定符。此类属性说明符仅适用于 标识符出现在其声明符之前。例如,在
__attribute__((noreturn)) void d0 (void), __attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void)
noreturn 属性适用于声明的所有函数; 格式属性仅适用于 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
}
编辑:
请务必注意,此属性是特定于平台的。我引用:
裸体
此属性在 ARM、AVR、MCORE、MSP430、NDS32、RL78、RX 和 SPU 端口上可用。它允许编译器构造 必要的函数声明,同时允许主体 函数作为汇编代码。指定的函数将没有 编译器生成的序言/尾声序列。只有基本的 asm 语句可以安全地包含在裸函数中(请参阅基本 Asm)。 虽然使用扩展的asm或基本asm和C代码的混合可能会 看似有效,不能依赖它们可靠地工作,并且 不支持。
引自 GCC 关于函数属性的文档。
旁注
可能进一步阅读 clang 属性可能会有所帮助(主要与 GCC 兼容),但这些评论似乎表明希望匹配 GCC 行为。
若要执行等效的 Visual C++ 代码,请完全在程序集中实现它,要么在单独的文件中,要么在顶级(而不是函数中)asm
语句中实现它。
- 为什么成员函数地址离自由函数这么远?
- MFC 消息映射中的函数地址
- 设置成员 GlobalCEFApp->OnWebKit使用函数地址初始化 C++生成器
- 在Visual C 中找到调用函数地址(安全)
- 获取函数地址时出现奇怪行为
- 函数地址
- 如何在C++中打印成员函数地址
- 为什么函数指针、函数地址和函数相同
- 匹配布尔值与常量 void* 重载的函数地址
- 函数地址和函数地址的地址没有区别吗?
- 在 Linux 库中查找静态函数地址
- 调用传递给 gcc 内联汇编器 (avr-gcc) 的 const 函数地址
- 使用32位应用程序从64位kernel32.dll获取函数地址
- 为什么函数地址不是常量表达式
- 将函数地址转换为 64 位整数:未定义/行为不当
- Visual Studio在打印函数地址时出错
- 获取有关函数地址的信息
- 通过函数地址调用另一个类的函数
- 打印成员函数地址的最简单方法是什么?
- 圆括号成员函数地址错误