转一个VB结合汇编提高VB效率的:比 SuperCopyMemory 还快的 IcyCopyMemory!
' IcyCopyMemory [code by iceboy] - 40% faster than RtlMoveMemory
' Tested on WinXP SP3 / E2160 oc 3Ghz / DDR2 800 - 2.79GB/s
' MSN: icediy#non-spam#hotmail#dot#com / QQ: 41785691
' API Declaration
Private Declare Function CallWindowProcW Lib "user32" (ByRef lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, ByRef lpflOldProtect As Long) As Long
Private Declare Sub RtlMoveMemory Lib "ntdll" (ByVal pDst As Long, ByVal pSrc As Long, ByVal dwLength As Long)
Dim Asm(37) As Long, AsmStub(1) As Long, AsmPtr As Long, IDEMode As Long
Private Const PAGE_EXECUTE_READWRITE As Long = &H40
Private Function RetLng(ByVal dwAny As Long) As Long
RetLng = dwAny
End Function
Private Sub InitAsm()
Dim FuncAddr As Long, OldProtect As Long
Asm(0) = &H8B575651: Asm(1) = &H8B10247C: Asm(2) = &H8B142474: Asm(3) = &H5118244C
Asm(4) = &HF33FE183: Asm(5) = &HE18359A4: Asm(6) = &H6850FC0: Asm(7) = &H5F000000
Asm(8) = &HCC2595E: Asm(9) = &H3E9C100: Asm(10) = &H8DCE348D: Asm(11) = &HD9F7CF3C
Asm(12) = &HCE84180F: Asm(13) = &H200&: Asm(14) = &HCE046F0F: Asm(15) = &HCE4C6F0F
Asm(16) = &H4E70F08: Asm(17) = &H4CE70FCF: Asm(18) = &H6F0F08CF: Asm(19) = &HF10CE44
Asm(20) = &H18CE4C6F: Asm(21) = &HCF44E70F: Asm(22) = &H4CE70F10: Asm(23) = &H6F0F18CF
Asm(24) = &HF20CE44: Asm(25) = &H28CE4C6F: Asm(26) = &HCF44E70F: Asm(27) = &H4CE70F20
Asm(28) = &H6F0F28CF: Asm(29) = &HF30CE44: Asm(30) = &H38CE4C6F: Asm(31) = &HCF44E70F
Asm(32) = &H4CE70F30: Asm(33) = &HC18338CF: Asm(34) = &HFA57508: Asm(35) = &H770FF8AE
Asm(36) = &HC2595E5F: Asm(37) = &HC&
AsmStub(0) = &HFF505A58: AsmStub(1) = &HE2&
AsmPtr = VarPtr(Asm(0))
FuncAddr = RetLng(AddressOf IcyCopyMemory)
VirtualProtect FuncAddr, 5, PAGE_EXECUTE_READWRITE, OldProtect
RtlMoveMemory FuncAddr, VarPtr(&HE9), 1
RtlMoveMemory FuncAddr + 1, VarPtr(AsmPtr - (FuncAddr + 5)), 4
VirtualProtect FuncAddr, 5, OldProtect, OldProtect
End Sub
Private Function SetIDE() As Boolean
IDEMode = -1
SetIDE = True
End Function
Public Sub IcyCopyMemory(ByVal pDst As Long, ByVal pSrc As Long, ByVal dwLength As Long)
If AsmPtr = 0 Then InitAsm
Debug.Assert SetIDE
If IDEMode = 0 Then
IcyCopyMemory pDst, pSrc, dwLength
Else
CallWindowProcW AsmStub(0), AsmPtr, pDst, pSrc, dwLength
End If
End Sub
调用方法如下:
Public Sub IcyCopyMemory(ByVal pDst As Long, ByVal pSrc As Long, ByVal dwLength As Long)
If AsmPtr = 0 Then InitAsm
Debug.Assert SetIDE
If IDEMode = 0 Then
IcyCopyMemory pDst, pSrc, dwLength
Else
CallWindowProcW AsmStub(0), AsmPtr, pDst, pSrc, dwLength
End If
End Sub
示例如下(在FORM中):
Private Declare Sub CopyMemory Lib "ntdll" Alias "RtlMoveMemory" (ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
Dim Src(10485760 - 1) As Byte, Dst(10485760 - 1) As Byte
Private Sub Form_Load()
Dim i As Long, t As Double
Show
Print "IcyCopyMemory Demo"
Print
' CopyMemory
t = Timer
For i = 1 To 100
CopyMemory VarPtr(Dst(0)), VarPtr(Src(0)), 10485760
Next
Print "CopyMemory: " & CStr((Timer - t) * 1000) & "ms"
Print
' IcyCopyMemory
t = Timer
For i = 1 To 100
IcyCopyMemory VarPtr(Dst(0)), VarPtr(Src(0)), 10485760
Next
Print "IcyCopyMemory: " & CStr((Timer - t) * 1000) & "ms"
End Sub
测试结果:
CopyMemory -> 2GB/s
SuperCopyMemory -> 1.9GB/s
IcyCopyMemory -> 2.79GB/s
逆向过程:
00402120 /$ A1 48404000 /mov eax, dword ptr [404048]
00402125 |. 85C0 |test eax, eax
00402127 |. 75 05 |jnz short 0040212E
00402129 |. E8 22FEFFFF |call 00401F50
0040212E |> A1 4C404000 |mov eax, dword ptr [40404C]
00402133 |. 85C0 |test eax, eax
00402135 |.^ 74 E9 \je short 00402120
00402137 |. 8B4424 0C mov eax, dword ptr [esp+C]
0040213B |. 8B4C24 08 mov ecx, dword ptr [esp+8]
0040213F |. 8B5424 04 mov edx, dword ptr [esp+4]
00402143 |. 50 push eax
00402144 |. A1 48404000 mov eax, dword ptr [404048]
00402149 |. 51 push ecx
0040214A |. 8B0D 3C404000 mov ecx, dword ptr [40403C]
00402150 |. 52 push edx
00402151 |. 50 push eax
00402152 |. 51 push ecx
00402153 |. E8 00F8FFFF call 00401958
00402158 |. FF15 14104000 call dword ptr [<&MSVBVM60.__vbaSetSy>; MSVBVM60.__vbaSetSystemError
0040215E \. C2 0C00 retn 0C
阅读(614) | 评论(0) | 转发(0) |