Программа CPUINFO
Программа CPUINFO определяет модель и характеристики процессора, пользуясь только что описанной нами методикой. Полученная информация выводится на консоль в следующем виде (для процессора Pentium Pro):
*CPU Information*, (C) A. Frolov, 1997
CPU model: 5
Vendor ID: GenuineIntel
CPU Signature 00000619
CPU Feature EDX 0000F9FF
CPU type: 0
CPU family: 6
CPU model: 1
CPU stepping: 9
FPU detected
В листинге 1.4 вы найдете исходный текст модуля, составленного на языке ассемблера. В этом модуле определены все функции, необходимые для распознавания процессора и получения его характеристик.
Листинг 1.4. Файл cpuinfo\askcpu.asm
; =====================================================
; Get CPU information
;
; (C) A. Frolov, 1997
;
; E-mail: frolov@glas.apc.org
; WWW: http://www.glasnet.ru/~frolov
; or
; http://www.dials.ccas.ru/frolov
; =====================================================
.model small
CPU_ID MACRO
db 0fh
db 0a2h
ENDM
.stack 100h
.data
public _vendor_id_msg
public _cpu_model
public _cpu_signature
public _features_ecx
public _features_edx
public _features_ebx
public _get_cpu_model
_vendor_id_msg db "............", 0dh, 0ah, "$"
_cpu_model db 0
_cpu_signature dd 0
_features_ecx dd 0
_features_edx dd 0
_features_ebx dd 0
.code
; ============================================
; _get_cpu_model
; ============================================
.8086
_get_cpu_model proc
call cpu_8086
cmp ax, 0
jz try_80286
mov _cpu_model, 0
jmp end_of_detect
try_80286:
call cpu_80286
cmp ax, 0
jz try_80386
mov _cpu_model, 2
jmp end_of_detect
try_80386:
call cpu_80386
cmp ax, 0
jz try_80486
mov _cpu_model, 3
jmp end_of_detect
try_80486:
call cpu_80486
cmp ax, 0
jz Pent_CPU
mov _cpu_model, 4
jmp end_of_detect
Pent_CPU:
mov _cpu_model, 5
.386
pusha
mov eax, 00h
CPU_ID
mov dword ptr _vendor_id_msg, ebx
mov dword ptr _vendor_id_msg[+4], edx
mov dword ptr _vendor_id_msg[+8], ecx
cmp eax, 1
jl end_of_detect
mov eax, 1
CPU_ID
mov _cpu_signature, eax
mov _features_ebx, ebx
mov _features_edx, edx
mov _features_ecx, ecx
popa
end_of_detect:
.8086
ret
_get_cpu_model endp
; ============================================
; cpu_8086
; ============================================
cpu_8086 proc
pushf
pop ax
mov cx, ax
and ax, 0fffh
push ax
popf
pushf
pop ax
and ax, 0f000h
cmp ax, 0f000h
je is_8086
mov ax, 0
ret
is_8086:
mov ax, 1
ret
cpu_8086 endp
; ============================================
; cpu_80286
; ============================================
.286
cpu_80286 proc
mov ax, 0f000h
push ax
popf
pushf
pop ax
and ax, 0f000h
jz is_80286
mov ax, 0
ret
is_80286:
mov ax, 1
ret
cpu_80286 endp
; ============================================
; cpu_80386
; ============================================
.386
cpu_80386 proc
pushfd
pop eax
mov ecx, eax
xor eax, 40000h
push eax
popfd
pushfd
pop eax
xor eax, ecx
jz is_80386
mov ax, 0
ret
is_80386:
push ecx
popfd
mov ax, 1
ret
cpu_80386 endp
; ============================================
; cpu_80486
; ============================================
cpu_80486 proc
pushfd
pop eax
mov ecx, eax
xor eax, 200000h
push eax
popfd
pushfd
pop eax
xor eax, ecx
je is_80486
mov ax, 0
ret
is_80486:
mov ax, 1
ret
cpu_80486 endp
end
Данный файл был оттранслирован при помощи пакетного файла, представленного в листинге 1.5.
Листинг 1.5. Файл cpuinfo\mk.bat
masm /Zi askcpu.asm,,,,
Главный файл программы приведен в листинге 1.6.
Листинг 1.6. Файл cpuinfo\cpuinfo.c
// =====================================================
// Определение типа процессора
//
// (C) Фролов А.В, 1997
//
// E-mail: frolov@glas.apc.org
// WWW: http://www.glasnet.ru/~frolov
// или
// http://www.dials.ccas.ru/frolov
// =====================================================
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <memory.h>
extern void GET_CPU_MODEL(void);
extern char VENDOR_ID_MSG[12];
extern char CPU_MODEL;
extern long CPU_SIGNATURE;
extern long FEATURES_ECX;
extern long FEATURES_EDX;
extern long FEATURES_EBX;
int main(void)
{
char buf[128];
printf("*CPU Information*, (C) A. Frolov, 1997\n\n");
GET_CPU_MODEL();
printf("CPU model: %d\n", (unsigned)CPU_MODEL);
if(CPU_MODEL >= 5)
{
memcpy(buf, VENDOR_ID_MSG, 12);
buf[12] = 0;
printf("Vendor ID: %s\n\n", buf);
printf("CPU Signature %08.8X\n", CPU_SIGNATURE);
printf("CPU Feature EDX %08.8X\n\n", FEATURES_EDX);
printf("CPU type: %d\n",
(CPU_SIGNATURE & 0x3000) >> 12);
printf("CPU family: %d\n",
(CPU_SIGNATURE & 0xF00) >> 8);
printf("CPU model: %d\n",
(CPU_SIGNATURE & 0xF0) >> 4);
printf("CPU stepping: %d\n\n", CPU_SIGNATURE & 0xF);
if(FEATURES_EDX & 0x1)
printf("FPU detected\n");
if(FEATURES_EDX & 0x800000)
printf("MMX supported\n");
}
getch();
return 0;
}