下面的例子完全用VB进行ASM编程的示例,本例获得CPU ID.
工程文件分为一个form1.frm 和一个模块module1.bas----------------------form1.frm的源文件---------------------VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   1965
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   3105
   LinkTopic       =   "Form1"
   ScaleHeight     =   1965
   ScaleWidth      =   3105
   StartUpPosition =   2  'Bildschirmmitte
   Begin VB.CommandButton Command1 
      Caption         =   "Get CPU Name"
      Height          =   495
      Left            =   840
      TabIndex        =   0
      Top             =   315
      Width           =   1425
   End
   Begin VB.Label Label2 
      Alignment       =   2  'Zentriert
      AutoSize        =   -1  'True
      BeginProperty Font 
         Name            =   "MS Sans Serif"
         Size            =   9.75
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   240
      Left            =   1515
      TabIndex        =   2
      Top             =   1065
      Width           =   60
   End
   Begin VB.Label Label1 
      Alignment       =   2  'Zentriert
      AutoSize        =   -1  'True
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   285
      Left            =   1515
      TabIndex        =   1
      Top             =   1350
      Width           =   75
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option ExplicitPrivate Sub Command1_MouseDown(Button As Integer, Shift As Integer, x As Single, Y As Single)    Label1 = ""
    Label2 = ""End SubPrivate Sub Command1_Click()
    
    Label1 = GetCpuName() & " CPU"
    Label2 = "You have a" & IIf(InStr("AEIOU", Left$(Label1, 1)), "n", "")End Sub ------------------------------end---------------------------------下面是modu1e.bas的源代码----------------------module1.bas的源文件--------------------------
Option Explicit
'
'This shows how to incorporate machine code into VB
'''''''''''''''''''''''''''''''''''''''''''''''''''
'The example fills the array with a few machine instructions and then copies
'them to a procedure address. The modified procedure is then called thru
'CallWindowProc. The result of this specific machine code is your CPU Vendor Name.
'
'##########################################################################
'Apparently it gets a Stack Pointer Error, but I don't know why; if anybody
'can fix that please let me know...                          [email protected]
'The Error is not present in the native compiled version; so I think it got
'something to do with the P-Code Calling Convention (strange though)...
'##########################################################################
'
'Sub Dummy serves to reserve some space to copy the machine instructions into.
'
'
'Tested on Intel and AMD CPU's (uncompiled and compiled)
'
'
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private x As LongPublic Function GetCpuName() As String
  
  Dim MachineCode(0 To 35)  As Byte
  Dim VarAddr               As Long
  Dim FunctAddr             As Long
  Dim EAX                   As Long
  Dim CPUName(1 To 12)      As Byte
  
  'set up machine code
    
    MachineCode(0) = &H55    'push ebp
    
    MachineCode(1) = &H8B    'move ebp,esp
    MachineCode(2) = &HEC
    
    MachineCode(3) = &H57    'push edi
    
    MachineCode(4) = &H52    'push edx
    
    MachineCode(5) = &H51    'push ecx
    
    MachineCode(6) = &H53    'push ebx
    
    MachineCode(7) = &H8B    'move eax,dword ptr [ebp+8]
    MachineCode(8) = &H45
    MachineCode(9) = &H8
    
    MachineCode(10) = &HF    'cpuid
    MachineCode(11) = &HA2
    
    MachineCode(12) = &H8B   'mov edi,dword ptr [ebp+12]
    MachineCode(13) = &H7D
    MachineCode(14) = &HC
    
    MachineCode(15) = &H89   'move dword ptr [edi],ebx
    MachineCode(16) = &H1F
    
    MachineCode(17) = &H8B   'mov edi,dword ptr [ebp+16]
    MachineCode(18) = &H7D
    MachineCode(19) = &H10
    
    MachineCode(20) = &H89   'move dword ptr [edi],ecx
    MachineCode(21) = &HF
    
    MachineCode(22) = &H8B   'mov edi,dword ptr [ebp+20]
    MachineCode(23) = &H7D
    MachineCode(24) = &H14
    
    MachineCode(25) = &H89   'move dword ptr [edi],edx
    MachineCode(26) = &H17
    
    MachineCode(27) = &H58   'pop ebx    MachineCode(28) = &H59   'pop ecx    MachineCode(29) = &H5A   'pop edx    MachineCode(30) = &H55   'pop edi
    
    MachineCode(31) = &HC9   'leave    MachineCode(32) = &HC2   'ret 16     I tried everything from 0 to 24
    MachineCode(33) = &H10   '           but all produce the stack error
    MachineCode(34) = &H0
    
    'tell cpuid what we want
    EAX = 0
    
    'get address of Machine Code
    VarAddr = VarPtr(MachineCode(0))
    
    'get address of Sub Dummy
    FunctAddr = GetAddress(AddressOf Dummy)
    
    'copy the Machine Code to where it can be called
    CopyMemory ByVal FunctAddr, ByVal VarAddr, 35 '35 bytes machine code
    
    'call it
    On Error Resume Next 'apparently it gets a stack pointer error when in P-Code but i dont know why
      CallWindowProc FunctAddr, EAX, VarPtr(CPUName(1)), VarPtr(CPUName(9)), VarPtr(CPUName(5))
      'Debug.Print Err; Err.Description
      'MsgBox Err & Err.Description
    On Error GoTo 0
    
    GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeName
    
End FunctionPrivate Function GetAddress(Address As Long) As Long    GetAddress = AddressEnd FunctionPrivate Sub Dummy()  'the code below just reserves some space to copy the machine code into
  'it is never executed    x = 0
    x = 1
    x = 2
    x = 3
    x = 4
    x = 5
    x = 6
    x = 7
    x = 8
    x = 9
    x = 10
    x = 0
    x = 1
    x = 2
    x = 3
    x = 4
    x = 5
    x = 6
    x = 7
    x = 8
    x = 9
    x = 10
   
End Sub 

解决方案 »

  1.   

    第二个例子:
    引用:http://www.vbdotcom.com/FreeCode.htm
    Call Pointer Call any function using its pointer. Including functions in dlls (both stdCall and declSpec), VB functions using AddressOf and functions in COM objects including AddRef and Release. 
    代码下载:
    ftp://www.vbdotcom.com/CallAnyFunctionByPtr.zip
    或 http://www.vbgood.com/vbdelphi/down/CallAnyFunctionByPtr.zip
    ''form
    Private Declare Function GetDC& Lib "user32" (ByVal hwnd As Long)
    Private Declare Function ReleaseDC& Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long)
    Private Sub Command1_Click()
    Dim a As Long, b As Long
    Dim s() As Byte, x As Long, y As Long
    s = StrConv("Hello !", vbFromUnicode)
    b = 15
    x = CallApiByName("user32", "SetWindowTextA", hwnd, VarPtr(s(0)))
    Debug.Print "x= ", x
    x = CallApiByName("kernel32", "RtlMoveMemory", VarPtr(a), VarPtr(b), 4&)
    Debug.Print "a= ", a
    x = CallApiByName("user32", "FlashWindow", hwnd, 1&)
    Debug.Print "x= ", x
    dc1 = GetDC(hwnd)
    x = CallApiByName("user32", "GetDC", hwnd)
    Debug.Print "x= ", x, "dc= ", dc1
    x = ReleaseDC(hwnd, dc1)
    End Sub
    ''bas
    Option Explicit
    ''***********************************************
    ''* This module use excelent solution from
    ''* http://www.vbdotcom.com/FreeCode.htm
    ''* how to implement assembly calls directly
    ''* into VB code.
    ''***********************************************
    Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
    Private mlngParameters() As Long ''list of parameters
    Private mlngAddress As Long ''address of function to call
    Private mbytCode() As Byte ''buffer for assembly code
    Private mlngCP As Long ''used to keep track of latest byte added to code
    Public Function CallApiByName(libName As String, funcName As String, ParamArray FuncParams()) As Long
    Dim lb As Long, i As Integer
    ReDim mlngParameters(0)
    ReDim mbytCode(0)
    mlngAddress = 0
    lb = LoadLibrary(ByVal libName)
    If lb = 0 Then
    MsgBox "DLL not found", vbCritical
    Exit Function
    End If
    mlngAddress = GetProcAddress(lb, ByVal funcName)
    If mlngAddress = 0 Then
    MsgBox "Function entry not found", vbCritical
    FreeLibrary lb
    Exit Function
    End If
    ReDim mlngParameters(UBound(FuncParams) + 1)
    For i = 1 To UBound(mlngParameters)
    mlngParameters(i) = CLng(FuncParams(i - 1))
    Next i
    CallApiByName = CallWindowProc(PrepareCode, 0, 0, 0, 0)
    FreeLibrary lb
    End Function
    Private Function PrepareCode() As Long
    Dim lngX As Long, codeStart As Long
    ReDim mbytCode(18 + 32 + 6 * UBound(mlngParameters))
    codeStart = GetAlignedCodeStart(VarPtr(mbytCode(0)))
    mlngCP = codeStart - VarPtr(mbytCode(0))
    For lngX = 0 To mlngCP - 1
    mbytCode(lngX) = &HCC
    Next
    AddByteToCode &H58 ''pop eax
    AddByteToCode &H59 ''pop ecx
    AddByteToCode &H59 ''pop ecx
    AddByteToCode &H59 ''pop ecx
    AddByteToCode &H59 ''pop ecx
    AddByteToCode &H50 ''push eax
    For lngX = UBound(mlngParameters) To 1 Step -1
    AddByteToCode &H68 ''push wwxxyyzz
    AddLongToCode mlngParameters(lngX)
    Next
    AddCallToCode mlngAddress
    AddByteToCode &HC3
    AddByteToCode &HCC
    PrepareCode = codeStart
    End Function
    Private Sub AddCallToCode(lngAddress As Long)
    AddByteToCode &HE8
    AddLongToCode lngAddress - VarPtr(mbytCode(mlngCP)) - 4
    End Sub
    Private Sub AddLongToCode(lng As Long)
    Dim intX As Integer
    Dim byt(3) As Byte
    CopyMemory byt(0), lng, 4
    For intX = 0 To 3
    AddByteToCode byt(intX)
    Next
    End Sub
    Private Sub AddByteToCode(byt As Byte)
    mbytCode(mlngCP) = byt
    mlngCP = mlngCP + 1
    End Sub
    Private Function GetAlignedCodeStart(lngAddress As Long) As Long
    GetAlignedCodeStart = lngAddress + (15 - (lngAddress - 1) Mod 16)
    If (15 - (lngAddress - 1) Mod 16) = 0 Then GetAlignedCodeStart = GetAlignedCodeStart + 16
    End Function
      

  2.   

    可以直接写代码吗?
    比如 mov ax,00000001
    那些机器码怎么记得住