使用 CPUID 指令可以从 processor 厂商里获得关于 processor 的详细信息,CPUID 指令是从 Intel 486 处理器以后开始加入支持。
1. 检测处理器是否支持 cpuid 指令
现在的处理器都支持 cpuid 指令,确实没必要去检测是否支持,除非在古老的机器上运行才有必要。
当然,这里只是作为一个知识点介绍,在 eflags.ID 标志位是 Processor Feature Identification 位,通过修改这个标志位的值,以此来检测是否支持 cpuid 指令。
;------------------------------------------------------- ; test cpuid enable ;------------------------------------------------------- pushfd ; save eflags mov eax, dword [esp] ; get old eflags xor dword [esp], 0x200000 ; xor the eflags.ID value popfd ; restore new eflags pushfd ; save eflags again pop ebx ; get new eflags cmp eax, ebx ; test eflags.ID is modify jne support ; OK! support CPUID instruction no_support: lea si, [failure_msg] mov ah, 0x0e xor bh, bh call printmsg jmp $ support: ... ... |
上面这个代码能成功地修改 eflags.ID 标志位,说明 cpu 是支持 cpuid 指令的。
2. cpuid 的使用方法
cpuid 指令由 eax 寄存器获得输入,执行 cpuid 指令前,将功能号传给 eax 寄存器:
输入:
输出:
所获得的 cpu 信息返回到 eax,ebx,ecx 以及 edx 寄存器,每一个功能所得到的信息格式是不一样的。
mov eax, 0 ; function 0 cpuid |
上面代码中,将功能号 0 来获取信息,那么它将返回值是:
- eax:最大的基本功能号
- ebx:"Genu"
- edx: "ineI"
- ecx:"ntel"
这几个字符串组合起来就是 "GenuineIntel" 对于 AMD 的处理器来说,它返回的字符串是:"AuthenticAMD"
下面代码用来测试 CPU 的厂商是 intel 还是 amd
mov eax, 0 cpuid test_intel: cmp ecx, 0x6c65746e jnz test_amd cmp edx, 0x49656e69 jnz test_amd cmp ebx, 0x756e6547 jnz test_amd lea si, [vendor_intel] call printmsg jz next_do test_amd: cmp ecx, 0x444d4163 jnz test_other cmp edx, 0x69746e65 jnz test_other cmp ebx, 0x68747541 jnz test_other lea si, [vendor_amd] call printmsg jz next_do test_other: lea si, [vendor_other] call printmsg |
简单地通过直接比较 ebx, ecx 和 edx 的值来确定。
3. 获得最大功能号
cpuid 返回的信号包括:
每种信息都有 CPU 所支持的最大功能号,扩展功能号以 0x80000000 开头
mov eax, 0 ; get largest basic function input cpuid mov eax, 0x80000000 ; get largest extended function input cpuid |
eax 寄存器返回的是 CPU 所支持的最大功能号,得到扩展最大功能号以 0x80000000 作为输入。
4. 得到 CPU 的基本功能信息
使用基本功能号 1 可以获得 CPU 的基本功能信息:
- eax 返回 CPU 的家族型号等
- ecx 和 edx 返回 CPU 的功能信息
mov eax, 1 cpuid mov esi, ecx mov ebx, ecx_feature_function_table call print_msg ;-------------------------------- ; input: ; esi: feature information ; ebx: function table ;-------------------------------- print_msg: xor eax, eax print_msg_loop: cmp eax, 31 jg print_msg_done lea edi, [ebx+eax*4] cmp dword [edi], 0 jnz do_print_msg inc eax jmp print_msg_next do_print_msg: mov edi, [edi] call puts bt esi, eax jc print_yes mov edi, no call puts jmp print_msg_next print_yes: mov edi, yes call puts print_msg_next: inc eax jmp print_msg_loop print_msg_done: ret yes db 'yes', 10, 0 no db 'no', 10, 0 ecx_msg: B0 db 'SSE3 Extension: ', 0 B1 db 'Carryless Multiplication: ', 0 B2 db '64-bit DS Area: ', 0 B3 db 'MONITOR/MWAIT: ', 0 B4 db 'CPL Qualified Debug Store: ', 0 B5 db 'Virtual Machine Extensions: ', 0 B6 db 'SaferMode Extensions: ', 0 B7 db 'Enhanced Intel SpeedStep Technology: ', 0 B8 db 'Thermal Monitor 2: ', 0 B9 db 'SSSE3 Extensions: ', 0 B10 db 'L1 Context ID: ', 0 B12 db 'Fused Multiply Add: ', 0 B13 db 'CMPXCHG16B: ', 0 B14 db 'Update Control: ', 0 B15 db 'Perf/Debug Capability MSR: ', 0 B17 db 'Process-context Identifiers: ', 0 B18 db 'Direct Cache Access: ', 0 B19 db 'SSE4.1: ', 0 B20 db 'SSE4.2: ', 0 B21 db 'x2APIC: ', 0 B22 db 'MOVEBE: ', 0 B23 db 'POPCNT: ', 0 B24 db 'TSC-Deadline: ', 0 B25 db 'AES: ', 0 B26 db 'XSAVE: ', 0 B27 db 'OSXSAVE: ', 0 B28 db 'AVX: ', 0 ecx_feature_function_table: dd B0 dd B1 dd B2 dd B3 dd B4 dd B5 dd B6 dd B7 dd B8 dd B9 dd B10 dd 0 ; reserved dd B12 dd B13 dd B14 dd B15 dd 0 ; reserved dd B17 dd B18 dd B19 dd B20 dd B21 dd B22 dd B23 dd B24 dd B25 dd B26 dd B27 dd B28 dd 0 ; reserved dd 0 ; reserved dd 0 ; 0 |
上面的代码读取 ecx,并显示出它的 feature 信息,下面是在 vmware 上的运行结果:
上面的信息是返回在 ecx 寄存器,返回在 edx 寄存器的信息是:
edx_msg: BIT0 db 'FPU: ', 0 BIT1 db 'VME: ', 0 BIT2 db 'DE: ', 0 BIT3 db 'PSE: ', 0 BIT4 db 'TSC: ', 0 BIT5 db 'MSR: ', 0 BIT6 db 'PAE: ', 0 BIT7 db 'MCE: ', 0 BIT8 db 'CMPXCHG8B: ', 0 BIT9 db 'APIC: ', 0 BIT11 db 'SYSENTER/SYSEXIT:', 0 BIT12 db 'MTRR: ', 0 BIT13 db 'PGE: ', 0 BIT14 db 'MCA: ', 0 BIT15 db 'CMOV: ', 0 BIT16 db 'PAT: ', 0 BIT17 db 'PSE36:', 0 BIT18 db 'PNS: ', 0 BIT19 db 'CLFSH:', 0 BIT21 db 'Debug Store:', 0 BIT22 db 'ACPI: ', 0 BIT23 db 'MMX: ', 0 BIT24 db 'FXSR: ', 0 BIT25 db 'SSE: ', 0 BIT26 db 'SSE2: ', 0 BIT27 db 'Self snoop:', 0 BIT28 db 'HTT: ', 0 BIT29 db 'TM: ', 0 BIT31 db 'PBE: ', 0 edx_feature_function_table: dd BIT0 dd BIT1 dd BIT2 dd BIT3 dd BIT4 dd BIT5 dd BIT6 dd BIT7 dd BIT8 dd BIT9 dd 0 ; reserved dd BIT11 dd BIT12 dd BIT13 dd BIT14 dd BIT15 dd BIT16 dd BIT17 dd BIT18 dd BIT19 dd 0 ; reserved dd BIT21 dd BIT22 dd BIT23 dd BIT24 dd BIT25 dd BIT26 dd BIT27 dd BIT28 dd BIT29 dd 0 ; reserved dd BIT31 |
运行结果如下:
示例代码:
http://download.csdn.net/detail/swanabin/6969253