0
我對如何基於SetPhysLong()在WINIO 3.0建立例程1字節/ 2字節訪問一個問題。構建例程WINIO V3.0基於SetPhysLong()
SetPhysLong()用於在DWORD(32位)的單位訪問內存,並且我的目標是建立自己的套路:
- SetPhysBYTE()以字節爲單位訪問內存( 8位無符號),並
- SetPhysWORD()在WORD(16位無符號)的單位訪問內存
有人告訴我,下面的方法可以解決這個問題:
- 使用GetPhysLong檢索當前DWORD內容
- 將新字節/字到DWORD的正確的部分
- 然後使用SetPhysLong到寫回
但我認爲上述方式失敗,如果下面的情況發生:
- 假設4字節的寄存器被映射到存儲器0x12345678的(因爲它是存儲器映射的IO)
- 假定寄存器的第二個字節是狀態寄存器並且屬性是「寫入1清除」和第二個字節現在是0x40
假設我們要寫0xA5到內存0x12345678。按照你的方式,我們得到:
- 使用GetPhysLong然後返回0x00004000
- 放的0xA5到LSB,我們得到了0x000040A5
- 使用SetPhysLong到0x000040A5設置爲內存地址爲0x12345678
這是不是正確,因爲值0x40將寫入第二個字節並將其清除爲0x00!
因此,我的目標是利用SetPhysBYTE(0×12345678,0xA5的)達到我的目的,不影響下面SetPhysLong()基於其它字節....
bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal)
{
PDWORD pdwLinAddr;
tagPhysStruct PhysStruct;
if (!IsWinIoInitialized)
return false;
if (g_Is64BitOS)
{
PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr;
}
else
{
// Avoid sign extension issues
PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr;
}
PhysStruct.dwPhysMemSizeInBytes = 4;
pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct);
if (pdwLinAddr == NULL)
return false;
*pdwLinAddr = dwPhysVal;
UnmapPhysicalMemory(PhysStruct);
return true;
}
[編輯]我已經解決了這個並請參考下面的代碼,如果需要...
bool _stdcall SetPhysBYTE(PBYTE pbPhysAddr, BYTE bPhysVal)
{
PDWORD pdwLinAddr;
tagPhysStruct PhysStruct;
if (!IsWinIoInitialized)
return false;
if (g_Is64BitOS)
{
PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr;
}
else
{
// Avoid sign extension issues
PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr;
}
PhysStruct.dwPhysMemSizeInBytes = 1;
pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct);
if (pdwLinAddr == NULL)
return false;
*(((PBYTE)((DWORD)pdwLinAddr))) = bPhysVal;
UnmapPhysicalMemory(PhysStruct);
return true;
}
bool _stdcall SetPhysWORD(PBYTE pbPhysAddr, WORD wPhysVal)
{
PDWORD pdwLinAddr;
tagPhysStruct PhysStruct;
if (!IsWinIoInitialized)
return false;
if (g_Is64BitOS)
{
PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr;
}
else
{
// Avoid sign extension issues
PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr;
}
PhysStruct.dwPhysMemSizeInBytes = 2;
pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct);
if (pdwLinAddr == NULL)
return false;
*(((PWORD)((DWORD)pdwLinAddr))) = wPhysVal;
UnmapPhysicalMemory(PhysStruct);
return true;
}