[英]gcc inlined assembly jmp address; Naked functions
我可以使用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.
為什么忽略我的裸屬性?
TL; DR在GCC中, 僅適用於:ARM,AVR,MCORE,MSP430,NDS32,RL78,RX和SPU端口
在x86上不可用 。
完整答案
(此答案的其余部分假定您使用的是受支持的目標)
那是因為您在GCC中使用Windows屬性語法__declspec
。
引用__declspec
上的MSDN參考 :
擴展屬性語法簡化並標准化了Microsoft特有的C和C ++語言擴展。
您應改為或並行使用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屬性適用於所有聲明的函數; 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
}
編輯:
裸
該屬性在ARM,AVR,MCORE,MSP430,NDS32,RL78,RX和SPU端口上可用。 它允許編譯器構造必要的函數聲明,同時允許函數主體為匯編代碼。 指定的函數將沒有編譯器生成的序言/結尾序列。 裸函數中只能安全地包含基本的asm語句(請參見基本Asm)。 雖然使用擴展asm或基本asm和C代碼的混合似乎可以工作,但不能依靠它們可靠地工作並且不受支持。
引用自GCC文檔中的函數屬性 。
邊注
可能對clang屬性進行進一步的閱讀可能會有所幫助(大部分與GCC兼容),但是這些注釋似乎暗示了人們希望匹配GCC行為。
要執行與Visual C ++代碼等效的操作,請在單獨的文件中或在頂層asm
語句(不在函數中)中完全以匯編形式實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.