2016-10-04 59 views
3

我有兩個名爲TestFunc和TestFunc2的空函數,我將它們的地址分配給兩個變量。指針的值與指定的值不同

void TestFunc() 
{ 
} 

__declspec(naked) void TestFunc2() 
{ 
} 

int main() 
{ 
DWORD* test = (DWORD*)TestFunc; 
DWORD* test2 = (DWORD*)TestFunc2; 

printf("TestFunc is %p at test is %p\n", TestFunc, test); 
printf("TestFunc2 is %p at test2 is %p\n", TestFunc2, test2); 
getchar(); 
} 

賦值後,兩個變量的值實際上與它們的賦值不同。

但是,在printf語句中,輸出顯示它們是相同的。任何想法爲什麼會發生?

Picture

+0

什麼是TestFunc和TestFunc2?功能?會員功能?變量?還有別的嗎?請嘗試創建[最小化,完整和可驗證示例](http://stackoverflow.com/help/mcve)並向我們顯示。 –

+0

我的不好,確實沒有。我打算使用DWORD *代替。但我的問題仍然存在,變量的值與他們分配的值不同。我在帖子中提到,TestFunc和TestFunc2是函數。 – eXPerience

+0

@eXPerience是調試還是發佈bulid?你在手錶的什麼位置看? – Amomum

回答

7

這是由incremental linking在Visual Studio中造成的,從這個頁面,您可以瞭解到這樣做的缺點之一是:

的增量鏈接程序在功能上等同於一個程序,是非增量鏈接的。然而,因爲它是爲後續增量鏈接,一個增量鏈接的可執行文件,靜態庫或動態鏈接庫文件製備:

  • 比由於代碼和數據填補的非增量鏈接程序大。填充使鏈接器可以增加函數和數據的大小,而無需重新創建文件。
  • 可能包含跳轉線來處理功能重新定位到新地址。

和那些跳的thunk是你所觀察到的東西。

如果禁用此選項(vs2015):

鏈接器 - >所有選項 - >啓用增量鏈接到沒有

那麼你的地址將是相等的。

如果你看一下在拆卸什麼是您已分配到DWORD *地址接近,你會發現有一個跳轉到你的函數:

TestFunc: 
000000014001117C jmp   TestFunc (01400116D0h) 
+0

就是這樣!感謝您的解釋。但是,在任務中沒有JMP。 http://puu.sh/rxrVA/8f4cef6f57.png – eXPerience

+0

您需要在DWORD指針變量中查找值,並檢查該位置的代碼。 – marcinj

1

它做特定的平臺運行時環境將您的代碼編譯爲。 C++允許運行時在場景後面執行一些指針算術。編寫任何依賴此運行時行爲的代碼是很危險的。

如果您真的想知道,請查看內存中的彙編代碼。我的猜測是運行時會使用一個額外的跳轉表,可能用於新的編輯和繼續調試功能,每個版本的Visual Studio都會改進/更改這些功能。