2010-11-25 48 views
2

我試圖在64位win7(amd64)上運行一些編碼爲32位vista(x86)的驅動程序,但它並未運行。經過大量的調試和試用後,我開始研究後者,但我不知道它的工作原因。這是我做過什麼:指針遞增差異黑白32位和64位

在很多地方,緩衝區指針指向的結構(在不同的地方不同)的陣列,並增加他們在一些地方使用了這種類型的語句:

ptr = (PVOID)((PCHAR)ptr + offset); 

而在一些地方:

ptr = (PVOID)((ULONG)ptr + offset); 

第二屆一個返航垃圾,所以我把它們全部改爲一日一。但是在第二個之後,我在網上發現了很多示例驅動程序。我的問題:

  1. 這些宏 在哪裏定義(谷歌沒有幫助太多)?
  2. 我明白所有的P_宏都是 指針,爲什麼指針 要ULONG?這是如何工作在32位的 ?
  3. PCHAR根據環境明顯改變寬度 。你知道有什麼地方可以找到這方面的文件嗎?

回答

3
  1. 它們應該在WINNT.H(它們是在SDK;沒有DDK在手)來定義
  2. ULONG是無符號長;在32位系統上,這是指針的大小。因此,指針 可以在不丟失的情況下來回轉換爲ULONG - 但在64位系統 (其中轉換該值將截斷該值)時不會如此。人們投到ULONG以獲得字節基指針 算術(儘管這具有未定義的行爲,正如您發現的那樣)
  3. 指針算術總是以基礎類型爲單位工作,即在PCHAR的CHAR中;這相當於算術字節
  4. 任何C書應詳細說明指針算術的精確語義。
3

此代碼在64位上失敗的原因是它將指針指向ULONG。 ULONG是一個32位的值,而64位的指針是64位的值。所以,當你使用ULONG強制轉換時,你將會截斷指針。

PCHAR強制轉換,假設PCHAR被定義爲char *沒有問題,只要其意圖是通過顯式數量的字節來增加指針。

這兩個宏都有相同的意圖,但只有其中的一個是有效的,其中指針大於32位。

指針運算就像這樣。如果您有:

T *p; 

,你做的事:

p + n; 

(其中n是一個數字),則P的值將n * sizeof(T)改變。

舉一個具體的例子,如果你有一個指向一個DWORD:

DWORD *pdw = &some_dword_in_memory; 

,並添加一個到它:

pdw = pdw + 1; 

,那麼你將被指向下一個DWORD。地址pdw指向將增加sizeof(DWORD),即4個字節。

您提到的宏使用強制轉換導致它們應用的地址偏移量乘以不同的數量。這通常只在已經傳遞BYTE(或char或void)緩衝區的低級代碼中完成,但知道其中的數據實際上是某種其他類型的。

+0

重新閱讀您的問題,我注意到它正在投射ULONG而不是ULONG *,所以我在回答的頂部添加了部分,我認爲這是最重要的部分。其餘的只是背景信息。 – 2010-11-25 14:05:51

1

ULONG在Windows SDK中的WinDef.h中定義,並且始終爲32位,所以當您將一個64位指針轉換爲ULONG時,會將指針截斷爲32位。