; Print processor characteristics using CPUID instruction. The CPUID ; instruction is supported on the Pentium and AMD 486 and higher. On ; older processors, an illegal instruction fault is generated. ; ; Example output on an AMD Duron model 3: ; ; flags = 00000246 edi = 00000000 esi = 8196E374 ebp = 0079FE28 esp = 0079FDF8 ; ebx = 68747541 edx = 69746E65 ecx = 444D4163 eax = 00000001 ; ; AuthenticAMD ; ; flags = 00000206 edi = 00000000 esi = 8196E374 ebp = 0079FE28 esp = 0079FDF8 ; ebx = 00000000 edx = 0183FBFF ecx = 00000000 eax = 00000630 ; ; MMX = Y ; SSE = N ; ; The first register dump is the result of CPUID with eax = 0. ; The 12 byte vendor string is in ebx:edx:ecx. The string is then printed. ; On Intel processors, the string is "GenuineIntel". ; ; The second register dump displays processor characteristics as described in ; http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/20734.pdf ; (for AMD processors). In particular, edx bits 23 and 25 are 1 if MMX and ; SSE instructions (respectively) are supported. In this example, bit ; 23 is 1 and bit 25 is 0. Also, the last 3 hex bytes of eax contain ; the processor type: 6 = AMD Duron, model 3, stepping 0. ; ; To compile using MASM and Borland C: ; ml /Cx /c cpuid.asm ; bcc32 cpuid.obj ; ; To compile using MASM and MINGW C: ; ml /Cx /c /coff cpuid.asm ; gcc cpuid.obj -o cpuid.exe ; .586 .model flat extern C printf: proc public _main .data msg byte 16 dup(0) ; vendor string fmt byte "%s", 10, 10, 0 ; format string for printing vendor string .code _main: ; Request CPUID vendor string and print registers xor eax,eax ; mov eax, 0 = retrieve vendor string in ebx, edx, ecx cpuid ; CPUID requires AMD 486 or Pentium call preg ; print registers ; Print vendor string, "AuthenticAMD" or "GenuineIntel" mov dword ptr [msg], ebx ; "Auth" mov dword ptr [msg+4], edx ; "enti" mov dword ptr [msg+8], ecx ; "cAMD" pushd offset msg pushd offset fmt call printf add esp, 8 ; Get processor info mov eax, 1 cpuid call preg ; print all registers ; Test bit 23 of edx for MMX support, print "MMX = Y" or "MMX = N" .data msg2 db "MMX = %c",10,0 .code mov eax, 'N' test edx, 800000h ; bit 23 = 1 if MMX is supported jz L1 mov eax,'Y' L1: push eax push offset msg2 call printf add esp, 8 ; Test bit 25 of edx for SSE support, print "SSE = Y" or "SSE = N" .data msg3 db "SSE = %c",10,0 .code mov eax, 1 cpuid mov eax, 'N' test edx, 2000000h ; bit 25 = 1 if SSE is supported jz L2 mov eax,'Y' L2: push eax push offset msg3 call printf add esp, 8 ret ; PREG prints all registers and flags (without changing them) .data s1 byte "flags = %08X edi = %08X esi = %08X ebp = %08X esp = %08X", 10, " ebx = %08X edx = %08X ecx = %08X eax = %08X", 10, 10, 0 .code preg: pushad pushfd push offset s1 call printf add esp, 4 popfd popad ret end