# VBForums CodeBank > CodeBank - Other >  Hava a look--Get the CPU name by ASM code!

## ENet

```
Option Explicit

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 Long

Function GetCpuName() As String

   Dim MachineCode(0 To 34) As Byte
   Dim VarAddr As Long
   Dim FunctAddr As Long
   Dim EAX As Long
   Dim CPUName(1 To 12) As Byte
   
   '设置机器代码
   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
   MachineCode(32) = &HC2
   MachineCode(33) = &H10
   MachineCode(34) = &H0
   EAX = 0
   VarAddr = VarPtr(MachineCode(0))          '得到机器代码的地址
   FunctAddr = GetAddress(AddressOf Dummy)   '得到子程序 Dummy的地址
                                             '把机器代码拷贝到能够被调用的地方
   CopyMemory ByVal FunctAddr, ByVal VarAddr, 35  '机器代码的长度为35比特
                                              
   Call CallWindowProc(FunctAddr, EAX, VarPtr(CPUName(1)), VarPtr(CPUName(9)), VarPtr(CPUName(5)))
   GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeName
End Function

Private Function GetAddress(Address As Long) As Long
   GetAddress = Address
End Function

Private Sub Dummy()
   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
```

----------


## Pino

I'm guesing this is not a question? I have moved to codebank!

----------


## penagate

Assembly bit was good, but VB needed a bit of work  :Wink: 



```
Public Function CPUname__ASM() As String
Static asmCPUIDProc(34) As Byte
Dim chCPUName(11)       As Byte

    asmCPUIDProc(0) = &H55   ' push ebp
    asmCPUIDProc(1) = &H8B   ' move ebp,esp
    asmCPUIDProc(2) = &HEC
    asmCPUIDProc(3) = &H57   ' push edi
    asmCPUIDProc(4) = &H52   ' push edx
    asmCPUIDProc(5) = &H51   ' push ecx
    asmCPUIDProc(6) = &H53   ' push ebx
    asmCPUIDProc(7) = &H8B   ' move eax, dword ptr [ebp+8]
    asmCPUIDProc(8) = &H45
    asmCPUIDProc(9) = &H8
    asmCPUIDProc(10) = &HF   ' cpuid
    asmCPUIDProc(11) = &HA2
    asmCPUIDProc(12) = &H8B  ' mov edi, dword ptr [ebp+12]
    asmCPUIDProc(13) = &H7D
    asmCPUIDProc(14) = &HC
    asmCPUIDProc(15) = &H89  ' move dword ptr [edi],ebx
    asmCPUIDProc(16) = &H1F
    asmCPUIDProc(17) = &H8B  ' mov edi, dword ptr [ebp+16]
    asmCPUIDProc(18) = &H7D
    asmCPUIDProc(19) = &H10
    asmCPUIDProc(20) = &H89  ' move dword ptr [edi],ecx
    asmCPUIDProc(21) = &HF
    asmCPUIDProc(22) = &H8B  ' mov edi,dword ptr [ebp+20]
    asmCPUIDProc(23) = &H7D
    asmCPUIDProc(24) = &H14
    asmCPUIDProc(25) = &H89  ' move dword ptr [edi],edx
    asmCPUIDProc(26) = &H17
    asmCPUIDProc(27) = &H58  ' pop ebx
    asmCPUIDProc(28) = &H59  ' pop ecx
    asmCPUIDProc(29) = &H5A  ' pop edx
    asmCPUIDProc(30) = &H55  ' pop edi
    asmCPUIDProc(31) = &HC9
    asmCPUIDProc(32) = &HC2
    asmCPUIDProc(33) = &H10
    asmCPUIDProc(34) = &H0

    CallWindowProc VarPtr(asmCPUIDProc(0)), _
                   0, _
                   VarPtr(chCPUName(0)), _
                   VarPtr(chCPUName(8)), _
                   VarPtr(chCPUName(4))

    CPUname__ASM = StrConv(chCPUName, vbUnicode)
End Function
```

----------


## Hack

Since this was more ASM than VB, I felt it belonged in Other.

----------


## wossname

Hack, thats silly, it enables VB6 programmers to use fast ASM code in their apps, it belongs in VB codebank.

This is excellent.

----------


## wossname

> Assembly bit was good, but VB needed a bit of work


Penagate, if I wanted to write my own ASM and use this technique, how would I know which bytes to put into the array?

Would I just write the program in MASM (for example), compile it and then use a hex editor to copy and paste the compiled bytes into the array?

Would I have to leave out certain bits of the compiled code?

Or will all this become clear once I've started to learn ASM?  I've just found
http://www.amazon.com/exec/obidos/tg...glance&s=books
on amazon.  Thinking of ordering it.

----------


## penagate

> Penagate, if I wanted to write my own ASM and use this technique, how would I know which bytes to put into the array?
> 
> Would I just write the program in MASM (for example), compile it and then use a hex editor to copy and paste the compiled bytes into the array?


That's basically it yes. I'd advise you use a program such as FASM, which only compiles the opcodes you type in, without any overhead of program structure. Perfect for this situation. As you said, once it's compiled you need to open the file (.BIN) in a hex editor and paste the bytes into your array initialiser.

Bear in mind, how you actually code the routine is language and call convention specific. Inline ASM in VC++ is very easy as the compiler allows you to access variables and arguments in the C++ code and simply compiles them as required. In VB, and I suppose C#, you need to know exactly where the variables are and how they are passed on the stack, so you can access them.

I have no real experience doing this using stdcall (the call convention used in VB) but I know in cdecl (C/C++ calling convention) the arguments are passed right to left on the stack. So to access them you can do this


```
int myfunc(int arg1, int arg2)
{
    _asm {
        mov eax, dword ptr [esp - 4]
        mov ebx, dword ptr [esp - 8]
    }
}
```

esp is the stack pointer register and you subtract 4 and 8 from that respectively to get the two 4-byte int variables we passed to the function.

I don't know what call convention C# uses (I presume that's what you'd be doing it in) so you'd have to read up on its finer details to get your precompiled ASM working. And be completely aware of the state of variables, etc. in the procedure, at the point at which you execute the ASM code.

----------


## wossname

Cool, thanks  :Smilie:

----------


## yrwyddfa

http://hackbase.com/hacker/program/2005080513018.html

Unless you wrote the source, you should indicate from where it came from.
It's a matter or politeness.

(and the code produces a stack pointer error in the VB IDE, too - it only works correctly when compiled to native code)

----------


## penagate

That is the silliest code. You need to call GetCpuName() to retrieve the CPU name yet every time you call it you copy the ASM code into another procedure and call that by using an API (why they did not just make that the function I do not know). It is so wasteful.

----------


## yrwyddfa

There's all sorts of variants of this function all over the web. Some are good, some are bad, but nearly all of them produce a stack pointer error when used with p-code, or in the IDE (because VB doesn't know how to correctly exit the function)

I think - but I'm not sure - that you're gonna need the techniques from Matt Curland's Advanced Visual Basic 6 book.

Look for the function delegator stuff to properly manage the stack so that VB can call arbitrary pointers to functions.

----------


## penagate

If you want to copy ASM code over a dummy VB function like they are trying to do here, you could at least do it properly. Give it a proper signature and call it from VB instead of an API for goodness sake. And you need a "ret" instruction in there as well.

----------

