下面的例子完全用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
以上为转载他人代码
工程文件分为一个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
以上为转载他人代码
解决方案 »
- 如何用MFC连接上MYSQL
- 怎样自定义文档格式
- CHttpFile 设置代理的问题
- 总算有了点进展,但还是有问题,请问这是为什么?
- UNICODE编程中的疑问!!有些函数好像没有UNICODE版的怎么办?
- 有关new的简单问题
- 何谓asp解释器,我用c++编的服务器,需要怎么和它连接?
- visual studio 6.0企业版安装问题?
- 100分求问?`
- 我想把一个工程的CScrollView 给改成 CEditView 应该如何做啊!!!
- Socket高手请进!在进行重叠IO时,可能会有上千个并发连接,但WSAWaitForMultipleEvents最多只能等待64个事件!
- 谁能谈谈vc++的编译选项。
asm有没有办法/
0F A2 CPUID EAX ?Processor identification informationDescription
Provides processor identification information in registers EAX, EBX, ECX, and EDX. This information identifies Intel as the vendor, gives the family, model, and stepping of processor, feature information, and cache information. An input value loaded into the EAX register determines what information is returned.Information Returned by CPUID InstructionInitial EAX Value Information Provided about the Processor0 EAX Maximum CPUID Input Value (2 for the Pentium ?Pro processor and 1 for
the Pentium processor and the later versions of Intel486?processor that
support the CPUID instruction).
EBX "Genu"
ECX "ntel"
EDX "ineI"
1 EAX Version Information (Type, Family, Model, and Stepping ID)
EBX Reserved
ECX Reserved
EDX Feature Information
2 EAX Cache and TLB Information
EBX Cache and TLB Information
ECX Cache and TLB Information
EDX Cache and TLB InformationThe CPUID instruction can be executed at any privilege level to serialize instruction execution. Serializing instruction execution guarantees that any modifications to flags, registers, and memory for previous instructions are completed before the next instruction is fetched and executed (see "Serializing Instructions" in Chapter 7 of the Intel Architecture Software Developer's Manual, Volume 3).When the input value in register EAX is 0, the processor returns the highest value the CPUID instruction recognizes in the EAX register (see Table 3-4). A vendor identification string is returned in the EBX, EDX, and ECX registers. For Intel processors, the vendor identification string is "GenuineIntel" as follows:EBX ?756e6547h (* "Genu", with G in the low nibble of BL *)
EDX ?49656e69h (* "ineI", with i in the low nibble of DL *)
ECX ?6c65746eh (* "ntel", with n in the low nibble of CL *)When the input value is 1, the processor returns version information in the EAX register and feature information in the EDX register (see Figure 3-3).The version information consists of an Intel Architecture family identifier, a model identifier, a stepping ID, and a processor type. The model, family, and processor type for the first processor in the Intel Pentium Pro family is as follows:
?Model?001B
?Family?110B
?Processor Type?0BSee AP-485, Intel Processor Identification and the CPUID Instruction (Order Number 241618), the Intel Pentium ?Pro Processor Specification Update (Order Number 242689), and the Intel Pe n t i u m ?Processor Specification Update (Order Number 242480) for more information on identifying earlier Intel Architecture processors.The available processor types are given in Table 3-5. Intel releases information on stepping IDs as needed.Type Encoding
Original OEM Processor 00BIntel OverDrive ?Processor 01B
Dual processor *10B
Intel reserved. 11BTable 3-6 shows the encoding of the feature flags in the EDX register. A feature flag set to 1 indicates the corresponding feature is supported. Software should identify Intel as the vendor to properly interpret the feature flags.BiT Feature Description
0 FPU桭loating-Point Unit Processor contains an FPU and executes the Intel 387
on Chip instruction set.1 VME梀irtual-8086 Processor supports the following virtual-8086 mode
Mode Enhancements enhancements:
?CR4.VME bit enables virtual-8086 mode extensions.
?CR4.PVI bit enables protected-mode virtual interrupts.
?Expansion of the TSS with the software indirection bitmap.
?EFLAGS.VIF bit (virtual interrupt flag).
?EFLAGS.VIP bit (virtual interrupt pending flag).
2 DE桪ebugging Processor supports I/O breakpoints, including the CR4.DE bitExtensions for enabling debug extensions and optional trapping of access
to the DR4 and DR5 registers.
3 PSE桺age Size Processor supports 4-Mbyte pages, including the CR4.PSE bit
Extensions for enabling page size extensions, the modified bit in page
directory entries (PDEs), page directory entries, and page table
entries (PTEs).
4 TSC桾ime Stamp Processor supports the RDTSC (read time stamp counter)
Counter instruction, including the CR4.TSD bit that, along with the CPL,controls whether the time stamp counter can be read.
5 MSR桵odel Specific Processor supports the RDMSR (read model-specific register)
Registers and WRMSR (write model-specific register) instructions.
6 PAE桺hysical Address Processor supports physical addresses greater than 32 bits, the
Extension extended page-table-entry format, an extra level in the page
translation tables, and 2-MByte pages. The CR4.PAE bit enables
this feature. The number of address bits is implementation specific.The Pentium ?Pro processor supports 36 bits of addressing when
the PAE bit is set.
7 MCE桵achine Check Processor supports the CR4.MCE bit, enabling machine check
Exception exceptions. However, this feature does not define the model-specific
implementations of machine-check error logging, reporting,
or processor shutdowns. Machine-check exception handlers might
have to check the processor version to do model-specific
processing of the exception or check for the presence of thestandard machine-check feature.
8 CX8桟MPXCHG8B Processor supports the CMPXCHG8B (compare and exchange 8
Instruction bytes) instruction.
9 APIC Processor contains an on-chip Advanced Programmable Interrupt
Controller (APIC) and it has been enabled and is available for use.
10,11 Reserved
12 MTRR桵emory Type Processor supports machine-specific memory-type range registers
Range Registers (MTRRs). The MTRRs contains bit fields that indicate theprocessor's MTRR capabilities, including which memory types the
processor supports, the number of variable MTRRs the processor
supports, and whether the processor supports fixed MTRRs.
13 PGE桺TE Global Flag Processor supports the CR4.PGE flag enabling the global bit in
both PTDEs and PTEs. These bits are used to indicate translation
lookaside buffer (TLB) entries that are common to different tasks
and need not be flushed when control register CR3 is written.14 MCA桵achine Check Processor supports the MCG_CAP (machine check global
Architecture capability) MSR. The MCG_CAP register indicates how many
banks of error reporting MSRs the processor supports.
15 CMOV桟onditional Processor supports the CMOV cc instruction and, if the FPU feature
Move and Compare flag (bit 0) is also set, supports the FCMOV cc and FCOMI
Instructions instructions.
16-22 Reserved
23 MMX?Technology Processor supports the MMX instruction set. These instructionsoperate in parallel on multiple data elements (8 bytes, 4 words, or 2
doublewords) packed into quadword registers or memory locations.
24-31 ReservedWhen the input value is 2, the processor returns information about the processor's internal caches and TLBs in the EAX, EBX, ECX, and EDX registers. The encoding of these registers is as follows:
?The least-significant byte in register EAX (register AL) indicates the number of times the CPUID instruction must be executed with an input value of 2 to get a complete description of the processor's caches and TLBs. The Pentium ?Pro family of processors will return a 1.
?The most significant bit (bit 31) of each register indicates whether the register contains valid information (cleared to 0) or is reserved (set to 1).
?If a register contains valid information, the information is contained in 1 byte descriptors. Table 3-7 shows the encoding of these descriptors.Descriptor Value Cache or TLB Description
00H Null descriptor
01H Instruction TLB: 4K-Byte Pages, 4-way set associative, 32 entries
02H Instruction TLB: 4M-Byte Pages, 4-way set associative, 4 entries
03H Data TLB: 4K-Byte Pages, 4-way set associative, 64 entries
04H Data TLB: 4M-Byte Pages, 4-way set associative, 8 entries
06H Instruction cache: 8K Bytes, 4-way set associative, 32 byte line size
08H Instruction cache: 16K Bytes, 4-way set associative, 32 byte line size0AH Data cache: 8K Bytes, 2-way set associative, 32 byte line size
0CH Data cache: 16K Bytes, 2-way set associative, 32 byte line size
41H Unified cache: 128K Bytes, 4-way set associative, 32 byte line size
42H Unified cache: 256K Bytes, 4-way set associative, 32 byte line size
43H Unified cache: 512K Bytes, 4-way set associative, 32 byte line size
44H Unified cache: 1M Byte, 4-way set associative, 32 byte line sizeThe first member of the Pentium Pro processor family will return the following information about caches and TLBs when the CPUID instruction is executed with an input value of 2:EAX 03 02 01 01H
EBX 0H
ECX 0H
EDX 06 04 0A 42HThese values are interpreted as follows:
?The least-significant byte (byte 0) of register EAX is set to 01H, indicating that the CPUID instruction needs to be executed only once with an input value of 2 to retrieve complete information about the processor's caches and TLBs.
?The most-significant bit of all four registers (EAX, EBX, ECX, and EDX) is set to 0, indicating that each register contains valid 1-byte descriptors.
?Bytes 1, 2, and 3 of register EAX indicate that the processor contains the following:?01H桝 32-entry instruction TLB (4-way set associative) for mapping 4-KByte pages.
?02H桝 4-entry instruction TLB (4-way set associative) for mapping 4-MByte pages.
?03H桝 64-entry data TLB (4-way set associative) for mapping 4-KByte pages.?The descriptors in registers EBX and ECX are valid, but contain null descriptors.
?Bytes 0, 1, 2, and 3 of register EDX indicate that the processor contains the following:?42H桝 256-KByte unified cache (the L2 cache), 4-way set associative,
with a 32-byte cache line size.
?0AH桝n 8-KByte data cache (the L1 data cache), 2-way set associative, with a
32-byte cache line size.
?04H桝n 8-entry data TLB (4-way set associative) for mapping 4M-byte pages.
?06H桝n 8-KByte instruction cache (the L1 instruction cache), 4-way set associative,
with a 32-byte cache line size.
Operands Bytes Clocks
2 14 NPFlags
None.
这是在程序员大本营(微软版)中的汇编资料中截取的cpuid指令的用法,上文的vb程序也是用的这个指令,有一符图没法贴,你可以自己去查。
可以在自己的程序中用db 0f0h,0a2h插入cpuid指令。
不过从上文看,cpuid指令好像没有能得到cpu唯一标识的功能,只能得到cpu的一些信息。
cpu唯一标识的详细资料 给我一份吧.不胜感激!!!
[email protected]
你好,你的资料可以给我一份吗?
[email protected]
不过好像可以利用“标专寄存器”来判断
; cpuid.asm
;
; CPU detector program.
;
; Copyright (c) 1993 by Borland International, Inc.
;
; Build with the provided makefile: make -B
TITLE CPUID
JUMPS
.model small
.stack 100h
.data
saved_cpuid dd ?
vendor_id db 12 dup (?)
cpu_type db ?
themodel db ?
stepping db ?
id_flag db 0
intel_proc db 0
id_msg db "This system has a$"
c8086 db "n 8086/8088 microprocessor$"
c286 db "n Intel 286 microprocessor$"
c386 db "n Intel386 (TM) microprocessor$"
c486 db "n Intel486 (TM) DX microprocessor$"
Pentium db " Pentium(TM) microprocessor", 13, 10, "$"
intel db "This system contains a Genuine Intel Processor", 13, 10, "$"
modelmsg db "Model: $"
steppingmsg db "Stepping: $"
familymsg db "Processor Family: $"
period db ".",13,10,"$"
dataCR db ?,13,10,"$"
intel_id db "GenuineIntel".code
.8086 ; This part of the program must run on an 8086
start: mov ax,@data
mov ds, ax ;set segment register
mov es, ax ;set segment register
and sp, not 3 ;align stack to avoid AC fault
call get_cpuid
call print
mov ax,4c00h ; terminate program
int 21hget_cpuid proc; 8086 CPU check
; Bits 12-15 are always set on the 8086 processor
;
check_8086:
pushf ;save FLAGS
pop bx ;store FLAGS in BX
mov ax, 0fffh ;clear bits 12-15
and ax, bx ; in FLAGS
push ax ;store new FLAGS calue on stack
popf ;replace current FLAGS value
pushf ;set new flags
pop ax ;store new flags in AX
and ax, 0f000h ;if bits 12-15 are set, then CPU
cmp ax, 0f000h ; is an 8086/8088
mov cpu_type, 0 ; save the CPU type
je end_get_cpuid
;
; Intel 286 CPU check
; Bits 12-15 are always clear on the Intel processor.
;
check_80286:
.286
or bx, 0f000h ;try to set bits 12-15
push bx
popf
pushf
pop ax
and ax, 0f000h ; if bits 12-15 are cleared,
; CPU=Intel 286
mov cpu_type, 2 ; turn on Intel 286 Cpu flag
jz end_get_cpuid ; if CPU is intel 286, check
; for Intel 287 math coprocessor; Intel386 CPU check
; The AC bit (bit 18), is a new bit introduced in the EFLAGS
; register on the Intel486 DX CPU to generate alignment faults.
; This bit can not be set on the Intel386 CPU.
;
check_intel386:
.386
pushfd
pop eax ;get original EFLAGS
mov ecx,eax ; save original EFLAGS
xor eax,40000h ;flip AC bit in EFLAGS
push eax ; save for EFLAGS
popfd ; copy to EFLAGS
pushfd ; push EFLAGS
pop eax ; get new EFLAGS value
xor eax,ecx ; can't toggle AC bit, CPU=Intel386
mov cpu_type, 3 ; turn on Intel386 CPU flag
je end_get_cpuid ; if CPU is Intel386, now check
; for an Intel 287 or Intel387 MCP; Intel486 DX CPU, Intel 487 SX MCP, and Intel486 SX CPU checking
;
; Checking for the ability to set/clear the ID flag (bit 21) in EFLAGS
; which diferentiates between Pentium (or greater) and the Intel486.
; If the ID flag is set then the CPUID instruction can be used to
; determine the final version of the chip, else it's a 486
;
;
check_Intel486:
.486
mov cpu_type, 4 ;turn on Intel486 CPU flag
pushfd ;push original EFLAGS
pop eax ; get original EFLAGS in eax
mov ecx,eax ;save original EFLAGS in ecx
or eax,200000h ; flip ID bit in EFLAGS
push eax ;save for EFLAGS
popfd ;copy to EFLAGS
pushfd ;push EFLAGS
pop eax ;get new EFLAGS value
xor eax,ecx
je end_get_cpuid ;if ID bit cannot be changed,
;CPU=Intel486 without CPUID
;instruction functionality; Otherwise, execute CPUID instruction to determine vendor,
; family, model and stepping.check_vendor:
.586
mov id_flag, 1 ; set flag for indicating use of
;CPUID inst
mov eax, 0 ;set up for CPUID instruction
cpuid
mov dword ptr vendor_id, ebx; Test for "GenuineIntel" vendor id.
mov dword ptr vendor_id[+4], edx
mov dword ptr vendor_id[+8], ecx
mov si, offset vendor_id
mov di, offset intel_id
mov cx, length intel_id
compare:
repe cmpsb
cmp cx, 0 ; must be a GenuineIntel if ecx =0
jne cpuid_dataintel_processor:
mov intel_proc, 1
mov [intel-1], ' ' ; add a space so the Genuine Intel
; message prints out.cpuid_data:
mov eax, 1
cpuid
mov saved_cpuid,eax ;save for future use
and eax, 0F00H ; mask everything but family
shr eax, 8
mov cpu_type, al ; set cpu_type with family mov eax,saved_cpuid ;restore data
mov stepping, al
and stepping, 0FH ; isolate stepping info mov eax, saved_cpuid
mov themodel, al
and themodel, 0F0H ; isolate model info
shr themodel, 4end_get_cpuid:
.8086
ret
get_cpuid endp;
; This procedure prints the appropriate cpuid string
; If the CPUID instruction was supported, it prints out
; the cpuid info.print proc
push ax
push bx
push cx
push dx
cmp id_flag, 1 ; if set to 1, cpu supported CPUID
; instruction
; print detailed CPUID information
je print_cpuid_data mov dx, offset id_msg
mov ah, 9h
int 21h ; print initial messageprint_86:
cmp cpu_type, 0
jne print_286
mov dx, offset c8086
mov ah, 9h
int 21h
jmp end_printprint_286:
cmp cpu_type, 2
jne print_386
mov dx, offset c286
mov ah, 9h
int 21h
jmp end_print
print_386:
cmp cpu_type, 3
jne print_486
mov dx, offset c386
mov ah, 9h
int 21h
jmp end_print
print_486:
mov dx, offset c486
mov ah, 9h
int 21h
jmp end_printprint_cpuid_data: cmp cpu_type, 5
jne print_cpuid_cont mov dx, offset Pentium
mov ah, 9
int 21hprint_cpuid_cont:
mov dx, offset familymsg ;print family msg
mov ah, 9h
int 21h
mov al, cpu_type
mov byte ptr dataCR, al
add byte ptr dataCR, 30H ; convert to ASCII
mov dx, offset dataCR ; print family info
mov ah, 9h
int 21h mov dx, offset steppingmsg ; print stepping msg
mov ah, 9h
int 21h
mov al, stepping
mov byte ptr dataCR, al
add byte ptr dataCR, 30H ; convert to ASCII
mov dx, offset dataCR ; print stepping info
mov ah, 9h
int 21h mov dx, offset modelmsg ; print model msg
mov ah, 9h
int 21h
mov al, themodel
mov byte ptr dataCR, al
add byte ptr dataCR, 30H ; convert to ASCII
mov dx, offset dataCR ; print stepping info
mov ah, 9h
int 21h
end_print:
pop dx
pop cx
pop bx
pop ax
ret
print endp end start